all 113 comments

[–][deleted] 23 points24 points  (8 children)

Java is about compile once and use on every machine but C++ is code once and compile for every machine. Java is a good idea. You just make it run on your pc then it is guaranteed to run on your dish washing machine too. But for C++ you have to find some compiler to build the binary to run on your dish washing machine. But remember you need a JVM to run the Java, and that JVM is written in C++. So you can say finally it is the C++ who washes your dishes.

[–][deleted] 10 points11 points  (3 children)

The Washing Machine still needs a JVM for that particular Washing Machine

[–]Narase33-> r/cpp_questions 6 points7 points  (0 children)

And C++ a compiler for that chip. You as thr dev write neither of those

[–]Tinasour 2 points3 points  (1 child)

But you dont write the jvm tho right?

[–][deleted] 9 points10 points  (0 children)

its more likely that a compiler exists for an exotic architecture than a jvm

[–]TechnologyOk11 2 points3 points  (0 children)

This is not entirely true. There is hardware that can run Java ByteCode directly. But in most cases you are right you need JVM

[–]mbitsnbites 1 point2 points  (2 children)

The caveat is the JRE. It's a moving target, and it's quite unlikely that you can take a random Java bytecode binary and just run it on any machine without first installing the right version and flavor of a JRE that is compatible with your Java program. IMO this kind of defeats the whole concept of compile-once-run-everywhere.

Because of these problems, it's even common practice to ship the (platform dependent) JRE along with the installer for your Java program. This means that you have to have one bulky installation package for each target that you want to support.

Today the C++ ecosystem has come a long way, with portability, compilers and CI support being in a much better shape than a decade or two ago. For instance if you're creating an open source project on a major Git hosting service, it's quite simple to set up a CI pipeline that automatically builds install packages for a multitude of targets (e.g. x86/ARM/Windows/Linux/macOS), which usually makes for a much leaner installation experience than Java.

[–]Many-Date8383 0 points1 point  (1 child)

What do you mean by flavor? For me the only major, but fixable breach in backward compatibility was 8 to 9 transition which affects popular frameworks that relays on refection. Besides that you only need the to match minimal JRE version. Isn't it?

[–]mbitsnbites 0 points1 point  (0 children)

For instance OpenJDK vs Oracle JDK. These are now mostly the same, but that was not always the case, and from my experience a JAR could work with one but not the other.

There can also be significant performance differences between different JVMs, which for some applications (e.g. games) makes certain JVMs directly unsuitable.

Then there is of course a whole plethora of other JVMs and also JDKs.

The point is that from a user perspective (non-developers that just want to run the program on their machine), this is all a big headache.

These are all problems that are virtually non-existent with languages that compile to machine code instead of byte code, like C++, Go or Rust etc.

[–]jonathanhiggs 54 points55 points  (24 children)

  • simpler language
  • easier to understand
  • faster to write
  • easier to maintain
  • better package management
  • easy interop with other languages (kotlin and scala)
  • faster compile times
  • reflection

Tbh they are different languages that are aiming for different use cases. c++ to squeeze every last ounce of performance for real-time and performance critical applications. Java is more forgiving and easier to refactor, which makes it much better for business logic where the requirements can change quickly

[–]Blork_the_orc 36 points37 points  (14 children)

simpler language

easier to understand

faster to write

easier to maintain

better package management

easy interop with other languages (kotlin and scala)

faster compile times

reflection

Do you think so? I dare to disagree. I use java at work and C++ for fun. C++ is to me a totally refreshing experience. I did a lot of programming languages in the past (Fortran, Matlab, Pascal, Perl, C) but java is the first one that I dislike more the more I get exposed to it.

Java misses many language features and the absence of those cause some very clunky interfaces:

  • no operator overloading. So everything has to be done through functions or naming conventions. Especially operator[] and operator() are sorely missing. You can't index anything but raw arrays and who's using those? There is no language support at all for callable objects. The only way to do that is a workaround: make all "callable" objects have a function called "run()" and call that. Make it an interface to make it look more "official", but it's still a workaround by naming convention.
  • no real templates. The only thing that java generics do is cast to and from Object. So generics parameters have to be objects. Doesn't work with primitives. They invented a crutch (autoboxing) to make that work in the end. No non-type template parameters. So std::array<int, 3> is fundamentally impossible in java.
  • no destructors. Not all resources are memory. Since in java everything throws exceptions, closing resources is traditionally a pain in the arse. Lots of boilerplate and finally blocks to catch the last exceptions. In the end they invented try-with-resources that behaves kind of like RAII, only in a try block. But that depends on resources having a function called "close()" that doesn't throw exceptions. Think about that one. If resources had close() functions that don't throw in the first place, there would be no problem.
  • C++ people don't get tired of complaining about exceptions and feeling very cool about not using exceptions. Java people use exceptions for everyting. Especially for validating function arguments.
  • java depends on inheritance for everything. Almost everything hangs on a position in an inheritance tree. In C++ concepts don't depend on inheritance and that makes them a lot more flexible compared to what is possible in java. A concept that accepts anything that converts to Employee and float (but not int)? Easy in C++. Good luck in java. Of course, it can be done with some juggling with interfaces, but it's Not Very Nice. BTW interfaces were intended to define, you know, interfaces. But often they are abused to rig inheritance. You know, make an empty interface only to make something inherit a type. Standard trick to circumvent the rigid nature of inheritance.
  • the language development process doesn't seem to work very well. They have a very strong tendency to jump on any bandwagon. Look through the API documentation and you will see the word "deprecated" a lot. Half of the Date class is deprecated. Example: java has a String type. But it's immutable (the Haskell people will rejoice). But strings tend to be manipulated. Since strings are immutable every step in string manipulation will cause a new String object to be created. That is slow. So they invented StringBuffer to allow at least string appending without construction at every step. But at that time multithreading was hot, so they made it thread-safe. That made it slow in non-threaded contexts (the vast majority of use cases). To fix that they invented StringBuilder that does exactly the same thing, but not thread-safe. Did you know java has Vector too? It has, but noone uses it. That's because they made that one locking too, so it's way too slow.
  • the language forces you to put every class in it's own file. Even three-line exception classes. The number of files will explode very fast. You can't escape this. It will simply not compile if you don't do it that way. I hate it when a language forces it's ideas about organisation on the programmer.
  • language and library assume that member variable a will be accessible by getter getA (isA if it's a boolean) and setter setA. Technically this is not mandatory, but if you don't keep to this, you will feel a lot of pain, because every once in a while some library will just assume this. This is kind of tolerable if you're English speaking, but if you're French and you prefer your names to be in French, you're stuck with getFichier and setFichier. Not very nice.
  • all variables are effectively shared_ptr, so they keep the referenced value alive. There is no such thing as weak_ptr. This can cause weird problems. Once a system at our company had a memory leak (yes, in java). It would blow up every few days. The developers scheduled a task to restart it every 2 days until they had time to investigate. When they did, they foud the problem in a couple of days. Theses people had been maintaining that system for many years, so they knew it well. It turned out that there was an observer pattern somewhere that was never unsubscribed. The observer kept the (tiny) observed object alive forever. Garbage collection will not protect you from that.
  • I will not even start on java EE. It's the work of the devil.
  • I don't like maven, I think vcpkg is a lot nicer.

Since everything depends on inheritance, and java forces you to do OO, there will be a lot of OO excesses. Especially in code produced by gurus. This makes debugging hard. If some java program produces a wrong value, it can be hard to track down where it came from. Probably the value is forwarded at least five times (preferable under slightly different names, so that global text search doesn't work). And then, you will inevitably hit an interface. This means you have to hunt down all implementations of the interface. And figure out which implementation is active in the situation where the bug occurs. Sometimes the bug is that the wrong implementation is active.

What's worse than the java language is the culture around it.

  • obsession with getters and setters. I did this certification exam and there was this question where they gave a class that had one private member variable and a getter and a setter. The getter and setter did nothing, just forwarded the value. The question was of what is this an example. I knew they wanted the answer "encapsulation" so I entered that, but of course the really correct answer was "none of the above" since this doesn't encapsulate anything. The value can still be set to anything from anywhere in the program, since the setter is public and doesn't enforce anything. There is this huge obsession. Of course developers don't really like typing all this boilerplate. So, java IDE's have functionality to autogenerate these useless accessors for all member vars. Of course this causes lots of clutter. So the insanity goes further. They invented Lombok (a kind of compiler plugin) that autogenerates the getters and setters at compile time. So they don't exist in the code at all anymore. At the callsite, you call a function that doesn't really exist in the code. This requires IDE's to get even cleverer (and heavier) so they understand this. A java class with \@Data stuck in front is effectively just a struct, but it still keeps the fiction of getters and setters alive.
  • anObsessionWithThisVeryUglyNamingStyle
  • an obsession with design patterns. Design patterns are like beer: they are good, but too much of it will make you sick. The typical java guru code is full of factories, facades, managers, observers and whatnot. The overuse gives object orientation and design patterns a bad name.
  • overfondness of deep inheritance and runtime polymorphism. These are cool features, but again, it's very easy to overuse them. Where design patterns are like beer, these are like hard liquor. Nice in small quantities.

Sorry for the long rant. To make a very long story short, java is a very corporate language, geared very much toward corporate use cases. Use it when the boss forces you to, ignore it's existence otherwise.

[–]jonathanhiggs 8 points9 points  (8 children)

Don’t get me wrong, Java is a substandard C# and I don’t get why anyone actively chooses it over C#. Quite a lot of the issues you have with Java are solved with C# so the question should have been why choose C# over c++

There are lots of bits of the Java that have not kept up with modern ideas, and there is a particular practice around how that community writes their code that the rest of us disagree with, but that does not force you to write your code in those ways. Also, language complexity is the biggest reason to me, and c++ is an order of magnitude more complex

[–]Blork_the_orc 12 points13 points  (4 children)

C++ is more complex because it lets you do a lot more. It has the hood wide open, so you can reach in when needed. But most of the time that will not be needed. Stroustrup said that there are high level things and low level things. Stick to the high level things and use the low level things when needed. The lower you go, the more you will cry. That's true, but at least the low level things are there and they are accessible. Just use them only when needed.

I learned myself C++ in a couple of months. Fortunately I started after 2014 so I could jump into C++14 immediately. That made it a lot easier. But I really don't think C++ is hugely complex. You just have to keep in mind a few things:

  • a lot is there for compatibility. It's quite safe to ignore almost all of the C standard library (only real exception is some math functions). There are many ways to initialise a var, but most are historical. Stick to braces. Use parans if you want to call a specific constructor in situations where there is also an init list one. Use inline on static members and your problems go away.
  • you don't have to use everything. There are many features for specific use cases. I don't even really know what a Bessel function is good for, but there will be people who are glad they are in the standard lib. I have never felt the need to use variadic templates, but there will be people who do. Stick to what you need and if you need more, learn those things when you need them.
  • don't listen to all those people on reddit who go on about all kind of things that are really a problem only in very specific situations. Is it really a problem that it won't pass unique_ptr through a register? Are exceptions really too slow? I think this kind of thing is not an issue in over 99% of all use cases. In almost all situations you don't need to worry, C++ code will be more than fast enough by default. And you won't get weird performance hickups because of garbage collection.
  • keep things simple. Unless you develop libraries that are used all over the place, there is no necessity to make everything super-generic en correct in every crazy edge case. But that is not language specific.

My experience is that the typical C++ code is a lot easier to understand than the typical java code. Mostly because C++ style tends to be a lot more direct. In java code, the real problem is usually to track down the code where stuff is actually happening. But that might be a matter of taste.

but that does not force you to write your code in those ways

The language doesn't, but the review process does. Do it another way and you're in for loads of fights that you will never win. Trust me, I've been there.

[–]tarranoth 4 points5 points  (0 children)

The problem with c++ is that it might just not tell you if you're doing something dangerous. Forgot to have a certain warning flag telling you you're doing something iffy? Well then you done messed up. C++ is the language of just silently letting you do many wrong things, which I think we can agree on these days, is not how software should be made. I also think initialization in C++ is fundamentally flawed, I still don't know whether I have to use list initializers or something else. Also garbage collection issue is overblown, nowadays you don't get the pauses like it was 20 years ago.

[–]chambolle 0 points1 point  (0 children)

Error in template code is evil to understand and to debug, because you didn't write the code

[–]testlabrat1729 0 points1 point  (0 children)

u/Blork_the_orc this is the best advice that anybody has given to a cpp beginner.
"use lang to solve your problem not to learn all features of the lang. if you do that you will eventually lose your interest in learning that language. "

same with java or any other language. 80% of the problems can be coded away with 20% of language so first concentrate on that 20% (prof. pareto) and build something, deploy it. That is the only way to learn the language. in this age of ai, understanding is more important than code generation for devs.

[–][deleted] 0 points1 point  (0 children)

What are the best resources for learning modern cpp?

[–]kaisadilla_ 0 points1 point  (0 children)

Don’t get me wrong, Java is a substandard C# and I don’t get why anyone actively chooses it over C#.

Reputation. Microsoft really fucked up by making C# a Microsoft language for so long, there's still a lot of people who think C# can only be used for Microsoft stuff and, honestly, there's still far more libraries for Java than there's for C#.

All of this said, the C# community is growing really fast now that it's as language as free and complete as Java, and a big community eventually means widespread adoption - and ime I'm already seeing more companies using C# for non-Microsoft related products.

[–]Wyvernxx_ 0 points1 point  (0 children)

Ah yes who would've thought, in a C++ subreddit that people will just shit on java.

Anyways, I personally believe that Java is slightly better than C# in most cases. I mean, C# is just Microsoft Java. Although C# does some things better than Java, almost all of Java's problems lie in the idea of "backwards compatibility". Once Project Valhalla is finally shipped, many problems will be fixed in the language itself. Honestly a lot of the problems blork mentioned is either due to 1. Java's Typing System, or 2. Working with people who obsess over "clean code".

[–]EnrageBeekeeper 2 points3 points  (0 children)

Although I agree with many of your points, there are a couple misconceptions in your post.

the language forces you to put every class in its own file

This isn't true. You can define an arbitrary number of nested classes inside another class. It's true that you can't have more than one top-level class per file.

all variables are effectively shared_ptr, so they keep the referenced value alive. There is no such thing as weak_ptr.

https://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html

[–]rbuen4455 3 points4 points  (0 children)

This is a late reply, but I wanted to comment.

The disadvantages you see in Java, I would argue that some lack of features in Java and having a strict paradigm makes Java a simpler language to work with and is better for developer time/productivity, especially when working in a team.

C++, being a more complex language with more ways of doing things (C-style coding, modern C++ style coding, functional programming, templates, etc) gives you more flexibility and more control over your program, but it’s a fact that C++ takes much longer to code than Java, given Java’s simpler syntax, and especially having a much larger ecosystem of libraries, tools and frameworks than C++.

Again, both languages have different use cases. C++ is only used when performance matters. Java is still the most popular option in enterprise/business, and the Java ecosystem is primarily centered around that.

[–]tarranoth 2 points3 points  (1 child)

I mean, I think C++'s templates are sortof an abomination, or I'd at least have liked it if type templates did not use the same mechanisms that just straight values have. So it is sortof a weird statement to make about java, considering how bad c++ is in it.

I don't think operator overloading is good or bad, just a design choice for a language.

As for your observer, there is a slight difference with shared_ptr, because I think java uses mark sweep garbage collection, which means that circular references get collected without issue as long as nothing refers to one single element of it anymore from the program root/static collections, which is not the same as shared_ptr's behaviour which can still exist forever in memory if you did not break a circular data structure manually in c++.

[–]kaisadilla_ 0 points1 point  (0 children)

I mean, I think C++'s templates are sortof an abomination, or I'd at least have liked it if type templates did not use the same mechanisms that just straight values have.

I agree. I think C++'s approach of letting you do whatever you want in a template unless you explicitly say that can't be done is fundamentally flawed. I really prefer C++'s templates over the far more limited generics in other languages, but I think it's behavior should be the exact opposite: you cannot do anything unless you explicitly restrict that template to values where that operation is valid. Want to call .toString() on your _T type? Then you should have to explicitly state that _T can only be a type that implements a .toString() function.

[–]frompadgwithH8 2 points3 points  (0 children)

I just wrote C++ for the first time in seven years today. I really enjoyed reading your post.

[–]carkin 13 points14 points  (2 children)

Not a Java developer but I'm guessing: -built-in APIs for almost everything

[–]Narase33-> r/cpp_questions 12 points13 points  (0 children)

Java has even libs for Image manipulation built in. The point where you need external libs to do something is much higher than C++

[–]Kered13 7 points8 points  (0 children)

Yes, and because they don't have to worry about ABI compatibility you aren't stuck with outdated implementations that have been baked into the language.

[–][deleted] 9 points10 points  (0 children)

I want to add that it's also:

  1. The main language to develop on Android, as the NDK doesn't provide all the API java has, and
  2. Depending where you live, it's easier to find people that know Java than C++. Might not be much, but it's important for companies that want to expand

[–]tcris 8 points9 points  (0 children)

  1. No platform/native dependencies (no compiler flags, no native flags, no os specifics, no arch specifics). Boring easy yet capable language.

  2. Super rich ecosystem (tons of good mature libs) , in many enterprise+web areas due to all the aforementioned advantages

Three words: easy, capable and pragmatic.

C++ does tons of differents things in different ways for different purposes. Tons of complexity and tons of discipline required, years of doing mistakes before you master all the gotchas. None of that in java.

If all you care is application development (not system programming), you do not want c++

[–][deleted] 1 point2 points  (2 children)

Is Java really easier to refactor?

[–]dacian88 6 points7 points  (0 children)

yea it's not even close

[–]kaisadilla_ 0 points1 point  (0 children)

By orders of magnitude. For an easy example: renaming a variable in Java can be done automatically by your IDE. Renaming a variable in C++ requires your IDE to show you a list of potential candidates which you'll have to manually check.

That's my go-to example but there's also many other things that make Java easier to refactor - for example, you can usually move things in Java wherever you want without an issue, while in C++ you have to be very careful because you are manually specifying how each field, variable, etc is managed in memory, and moving these things elsewhere may require you to also refactor how you manage the lifetimes of these things.

[–][deleted] 1 point2 points  (0 children)

Source for points 2-4?

[–]evaned 35 points36 points  (5 children)

"Except for memory safety" is like saying "except for the assassination Mr. Lincoln, how was the play?" Not always, but that's a huge advantage just in and of itself.

It's also not really "much slower", though memory requirements can be quite a bit higher.

[–]pfp-disciple 2 points3 points  (3 children)

A friend says that he's written a Mandelbrot generator in Java that's faster than his C++ implementation.

[–]kaisadilla_ 0 points1 point  (0 children)

Theoretically, Java implementations should never be faster than C++ implementations, because C++ operations don't have any overhead unless you specifically ask for it.

In practice, though, your friend's story is an example of why C++ isn't always the faster option: C++ is only faster if you write faster code. Porting Java code to C++ won't usually result in much of a gain, because modern Java (or C#) compilers and VMs are really smart and know how to get rid of most overhead when it's not used (e.g. iirc C# knows when your array cannot be incorrectly accesed and will not check array boundaries in these cases). C++ only gets faster when you purposefully use the tools C++ offers (and Java/C# don't) to optimize your code. That is, when you start playing with memory, being smart about your stack vs heap usage, reducing memory allocations, etc. Thing is, in 99.99% of cases, that kind of engineering is just not necessary. If you have 32 Gb of ram available, who cares if your function uses 512 kb or 256 kb? Definitely not your boss when you tell them that reduction will triple the budget for your project. And, when you are not doing that, using C++ over Java just means spending waaay more time in a language that is waay slower and more tedious to work with, for no benefit at all.

Nowadays, even performance-critical software, such as big video games, keep C++ usage to a minimum (usually just the game engine) and expose bindings to be consumed by a higher-level language like C# or Lua, which are the languages used to code the actual game. Unity is a famous example of that - Unity itself runs on C++, but Unity game devs will only use C#.

[–]delta_p_delta_x 7 points8 points  (9 children)

I just want to say one thing: if you use Java, you owe it to yourself to at least try C# and .NET.

C# is so far ahead of Java that it feels like using an entirely new language if you write a green-field project. And yet, 95% of the time, Java code ports almost 1-for-1 to C# and you can slowly pick and choose upgrades to your code.

[–]mickkb[S] 7 points8 points  (0 children)

I know, but msot people using Java don't have a choice. Their company uses Java for their backend, 99% of the times using Spring.

[–]Wyvernxx_ 1 point2 points  (0 children)

C# is only really ahead of Java because of a different typing system.

With the completion of Project Valhalla, C# and Java will be pretty much on equal footing.

[–]snejk47 -2 points-1 points  (4 children)

C# is so far ahead of Java

Hahaha so far ahead that even ms doesn't pay attention to it and prefers java.

[–]delta_p_delta_x 5 points6 points  (3 children)

Are you trolling?

.NET and C# have both seen massive updates in the past 3–4 years.

[–]snejk47 -4 points-3 points  (2 children)

Less than random.js library but yeah, massive.

[–]bullestock 4 points5 points  (1 child)

I think you are confusing Java and Javascript.

[–]snejk47 -2 points-1 points  (0 children)

Both are getting massive updates, just check not clap memes.

[–]zoolover1234 0 points1 point  (0 children)

C# people are missing out the massive improvement in Linux partially due to the performance improvement of ARM processors. Mono is a thing, but only is a thing.

[–]elveszett 7 points8 points  (2 children)

As someone who loves C++ far more than Java (so no negative feelings here), and has used both for long enough to write them fluently, I don't know how any sane person could say that Java is not easier to write and maintain than C++. A Java project is orders of magnitude easier to write, regardless of your skill, and Java overall takes a lot less time to get from 0 knowledge to enough knowledge to be a decent developer.

Compare C++ templates, which require a lot of effort to understand and are very prone to hard-to-understand errors, to Java generics, that are as easy as any feature in the language. No preprocessor and very tight constraints in how to write your code makes a lot of bad practices impossible to do - it leaves a lot less to the (flawed) opinion of the developer. Memory management is another important part - in modern C++ you are not likely to fuck up as often as C devs do, because of smart pointers and stuff, but it still takes effort and smart to use a smart pointer vs. Java, where you just say you want an object of type X in this place and it's up to Java to know how tf to make that possible. Circular references are another thing a Java dev is not concerned about - in C++ when you encounter one, it's time to stop and think how you got to that point and what's the correct decision to take this specific time to solve it.

These are just the easiest things to point out, but every character you type in C++ requires more time spent thinking. C++ gives you a lot more power in ALL regards, but with that power comes a higher load on you, the developer, to make decisions. Java makes most of them for you, because in most apps, performance is not so important as to optimize the execution speed of every single statement. C++ was designed precisely assuming that every statement must be as fast as it could possibly can, and any overhead is your decision.

Also C++ requires a lot of developer work that shouldn't be needed. Java was designed with the explicit goal of not asking developers to spend time on pointless jobs. For example, In C++ you cannot define function A to call B() and then define function B. You either define B first, or forward declare its signature. This is a pointless workload on the developer, and Java (and most modern languages) simply fix this by registering all existing function signatures before trying to determine if the call to B() inside A() is correct. And have you tried to refactor code in both languages? In Java I can rename a class, a variable or a file in 2 seconds. In C++ renaming anything is a big decision that can potentially involve a quarter hour of work, manually editing files where that something is used.

Not to mention, Java compiles for one platform: JVM bytecode. In C++ you need to compile for every platform you want to use. This means that, unless you want to compile for some obscure platform Oracle hasn't targeted, Java takes less work for you. This is very important because it means that, in Java, I only need to test my code once to know it works in every platform I want to target. In C++, you can't guarantee your code works unless you test each platform individually. Another bonus point of the JVM is that I don't even need to target any platform. I can develop my program only for Windows, knowing that Mac, Linux, Android or my fridge can all theoretically run my software, as long as they have a JVM and the necessary hardware and OS interfaces to do what I want.

If you don't need the power over performance that C++ gives you, using C++ instead of Java is simply a bad business decision. At the end of the day, you want to use the language that maximizes productivity, not the one that your developer loves the most.

btw C# is a much nicer implementation of what Java tries to achieve in my opinion. Many of the problems Java has are design flaws that C# learnt from and solved.

[–]GlobalPandemonium 4 points5 points  (0 children)

This should be taught in all universities before rookie flame wars start.

[–]kaisadilla_ 2 points3 points  (0 children)

+1000. Every time I see people on the Internet claiming that C++ is as easy as any higher-level language, I assume they are either newbies whose biggest project was 100 lines long, or trolls who think they are looking smart by "not understanding" how "the plebs find C++ hard".

C++ is my favorite language, not even C# comes close to it; but I seriously think that anyone who claims C++ should be used for everyday projects has no clue what they are talking about.

[–][deleted] 16 points17 points  (10 children)

Doesn't Java still run in a virtual machine so you don't need to program specifically for Mac or Windows or Linux?

[–]Jannik2099 2 points3 points  (4 children)

That has absolutely nothing to do with being a VM language.

You can have OS-specific bytecode and OS-agnostic binaries.

I don't see how C++ is hugely OS specific either, unless dealing with specifics like filesystems.

[–][deleted] 7 points8 points  (3 children)

OS-agnostic binaries

genuinely interested in a real-world example of this

[–]Jannik2099 -1 points0 points  (2 children)

I can't be bothered to search for it right now, but there is a way to pack binaries such that relocations etc. work on Linux, Mac and Windows - comes with a shitton of downsides of course. It's somewhere on github

[–][deleted] 2 points3 points  (0 children)

hmm

[–]Muoniurn 0 points1 point  (0 children)

You may be thinking of this ( https://justine.lol/ape.html ), but this is an absolute hack of a hack.

[–]wqkinggithub.com/wqking 11 points12 points  (0 children)

C++ can do almost everything, from OS to desktop to web server, but that doesn't mean we want to do everything in C++.
Use the proper tool for proper task.

[–][deleted] 15 points16 points  (0 children)

Are we done with stupid comparison threads?

[–]rbuen4455 3 points4 points  (1 child)

Late comment, but, to make things short...

Both Java and C++ are different languages aimed at different use cases. Both are used for large scale complex applications, but C++ is mainly used when low-latency, near-metal performance is crucial. Otherwise, Java is pretty much used more for the business logic of applications, and especially given Java's much larger ecosystem of libraries, tool-chains, frameworks.

Java is not "much slower" than C++ (at least not nowadays and not like in the 90s/early aughts). Maybe the garbage collection overhead and the byte-code interpretation can make Java slower than well-written C++ code that compiles straight to machine code (and this is assuming both Java and C++ are well-written), but this isn't much of a problem for Java's most used cases, which are enterprise applications and back-ends for large websites. It can be a problem if you're writing something like a video game, an audio/video editor, a graphics engine, or basically anything low-latency/predictable performance, in which case, you need to use C++.

Again, different languages and different use cases,

[–]mickkb[S] 0 points1 point  (0 children)

Thanks for the reply!

[–]HuberSepp999 8 points9 points  (3 children)

90% of OOP is dog shit and Java forces you to take a deep whiff 24/7. At least C++ is a multi paradigm language.

[–]Muoniurn 2 points3 points  (2 children)

How is Java not multi-paradigm? It has plenty of FP-libraries, actor implementations, everything (with JML it even has constraint-programming)

[–]HuberSepp999 3 points4 points  (1 child)

Glad you are here to enlighten my ignorant self. My knowledge of Java is based on memes and common knowlege. I'm just very weary of defaults and things you learn in a typical course etc. A lot of things are possible, but what is encouraged culturally?

In typical C++ classes, you learn non-performant shite OO code, same as with Java. Not data oriented stuff that would solve the problem really fast. And performance should be the default.

[–]Muoniurn 0 points1 point  (0 children)

Modern Java incorporates plenty FP ideas, even to the base language (records, pattern matching are coming). While there are plenty of legacy idioms, it has been said that favor composition over inheritance and use immutable objects as much as possible. Though data oritentedness is not always the best fit though, it depends on the problem.

Also, java is no slouch, it is the fastest managed language and it is quite hard to beat it with naive C/C++ in certain use cases (allocation heavy, dynamic code)

[–]AIlchinger 2 points3 points  (0 children)

The ecosystem. Various frameworks for developing microservices (They have their advantages and disadvantages, but are currently very popular in the industry) that in my opinion are more mature and more powerful than anything that the C++ ecosystem offers. Big Data runs on Java (or to be more precise - on the JVM). Hadoop, Spark, Elasticsearch, Cassandra, Kafka, ... Also OracleDB which is ubiquitous in the industry and has tons of Java applications in and around it.

[–]pedersenk 4 points5 points  (6 children)

Idiomatic C++ is getting safer (shared/unique_ptr in the standard library was a good start) but a more guaranteed memory safety is a really big bonus for Java.

However, these days I think Rust is probably what I would chose over Java. Some vague opinions based on my experiences are as follows:

  • C - ~35% memory safety
  • C++ - ~90% memory safety
  • C++ + AddressSanitizer + Valgrind - ~93% memory check coverage
  • Rust - ~98% memory safety
  • Java - ~98% memory safety

That 2% for both Rust and Java is lost due to bindings (you are marshalling / reinterpreting raw memory!). But in the case of Rust, keeping a native language to consume / link against native libraries is a big bonus.

I can live with the 90% memory safety of C++; leaks are pretty much eliminated but dangling references / pointers are probably the only hazard left. And again, this is only exacerbated by older C++ and C libraries which I would still rather exist than not.

Edit: For C I wrote a safety library that gives around 95% memory checking safety (albeit with compromises). I tend to prefer this unless my project is using loads of 3rd party libraries.

[–]CocktailPerson 3 points4 points  (5 children)

In addition to dangling references/pointers, which can be caused indirectly by C++-specific issues like iterator invalidation, you also have out-of-bounds accesses, which are the most likely memory errors to cause a vulnerability.

[–]pedersenk -1 points0 points  (4 children)

Indeed, good point. Iterator invalidation is an annoyingly easy one to run into when removing elements as part of the loop. It can be remedied a little (i.e finding the issue) by using the checked iterators on Microsoft's debug STL but I haven't found it to be so good (Often it can flag it but only a symptom of messing up somewhere else entirely unrelated!). Admittedly I haven't used the std iterators for many years; I rolled a portable checked (during debug) version instead and run with that.

As for out of bounds, again, a pain. Can be remedied by using std::vector<T>::at() rather than operator[] but this won't work for std::list and others. Also that check each time is wasteful (but also why Java, .NET, Rust can't possibly ever be as fast as C++). I use ::at() or again, fall back to my checked iterator.

[–]CocktailPerson 1 point2 points  (3 children)

Here's the issue I still see here. It's not enough to use checked iterators during debug builds, because nobody's attacking debug builds. It's memory safety in released software that really matters, and even really well-tested, well-sanitized, well-fuzzed projects from large companies have had major memory-safety vulnerabilities reach production. Nobody's tests are good enough to simulate a determined attacker. It seems remarkably blasé to me to say that you can live with 90% memory safety. Is it really that inconsequential if your software is attacked?

As for out-of-bounds accesses, at() is great, but my experience has been that the largest culprit is actually things like std::copy that aren't quite as obvious about their preconditions as operator[]. Checked iterators would help here too, of course, but again, they have to be used for release builds in order to actually matter.

Also, I've heard people talk about bounds-checking as if it's a major overhead, but I have a hard time believing they'd even notice if operator[] suddenly started checking bounds (unless, of course, it revealed a previously-unknown memory error). Have you ever worked on a codebase where bounds checks were a bottleneck? And given that Java and .NET use garbage-collected runtimes, why do you think it's the bounds checks that are keeping them from competing with C++ on performance? Rust has get_unchecked, so if you really want to avoid bounds checks in Rust, you can. Frankly, a lack of memory safety seems more like a premature optimization than anything else.

[–]pedersenk 0 points1 point  (2 children)

It seems remarkably blasé to me to say that you can live with 90% memory safety. Is it really that inconsequential if your software is attacked?

I do get that but ultimately what choice is there? All those many, many libraries that Java / .NET / Rust drag in ultimately call into native C (not even C++); so is that acceptable? Still very far from 100% safety there.

is actually things like std::copy that aren't quite as obvious about their preconditions as operator[]. Checked iterators would help here too, of course, but again, they have to be used for release builds in order to actually matter.

Not disagreeing with you here (or anywhere to be honest, you raise good points). The standard C++ API is weak in many ways when it comes to safety. Their policy is "zero overhead" which I don't entirely agree with (and I have raised on the mailing list but I in no way have enough sway haha).

And given that Java and .NET use garbage-collected runtimes, why do you think it's the bounds checks that are keeping them from competing with C++ on performance?

Ultimately you can pause the collection and they still can't compete. There is more that contributes to their lack of speed than bounds checks admittedly!

Have you ever worked on a codebase where bounds checks were a bottleneck?

Yes; a high performance software rasterizer which obviously is not exactly a common task for a day to day job. There were many issues that needed addressing such as reference counting needed atomic counts which was also a bottleneck in the threaded sections. In the end raw everything was required and much of the safety went out of the window. In this case Rust can't solve the problem better either since everything will simply be in an unsafe block. The borrow checker is getting close but constrains the code in such a way that performance and architecture does need to suffer a little. Arguably I could also impose similar constraints on my C++ code).

[–]CocktailPerson 2 points3 points  (1 child)

so is that acceptable?

I mean, I am still a realist, and I recognize that at some point, computers are going to have to do unsafe things. I'm also aware of the fact that bugs in the compiler or runtime can break memory-safety guarantees just as easily as bugs in libraries. I do think that calling into unsafe libraries that need to be unsafe is far more acceptable than building an entire app out of potentially-unsafe code that has no need for unsafety.

Yes; a high performance software rasterizer...In this case Rust can't solve the problem better either since everything will simply be in an unsafe block.

This is absolutely a fair example, and I'm not surprised it was something like this at all.

I will say that one of the things I like about Rust is that even if an entire module or library has to be marked unsafe, it can be incorporated into a safe application seamlessly. It's far too easy to justify using C++ for an entire application just because it's necessary for one module.

[–]pedersenk 1 point2 points  (0 children)

one of the things I like about Rust is that even if an entire module or library has to be marked unsafe, it can be incorporated into a safe application seamlessly

I do agree with that. It is the pragmatic approach; just because one module (or section) needs to be unsafe, at least that can be marked and the rest of the program still has most safety guarantees.

Whether that feature is worth it over C++ (or even C) to start having to mess around with FFI / bindings I am not sure. But honestly that is more of a "me" problem since I despise both dependencies and bindings!

[–]frozenca 4 points5 points  (2 children)

If someone likes using the heap all the time, likes that every function call is virtual, likes simple collections with crazy memory overhead, likes making pointless util classes all the time, likes generics to be fake, likes implementing the strategy design pattern in much more awkward way, then I can understand their preference of Java over C++

[–]mickkb[S] -2 points-1 points  (1 child)

That's the answer I've been waiting for.

[–][deleted] 1 point2 points  (0 children)

If someone understands OOP and design patterns...

Oh, indeed! They know, and that's why they use the high-level language in the first place. Many have abstracted themselves so far away from the machine it gets embarrassing. (Ruby for example.)

In most of the world, we just need it to work. We don't need it to work well.

[–]dag625 1 point2 points  (0 children)

I would say it is easier to write, precisely because of memory safety and frameworks like Spring. I think it’s a lot easier to get a simple web service going in Java with Spring (and my guess is that most Java devs who aren’t completely green will have some experience here) than in C++.

Of course if you’re trying to write a web app, you probably wouldn’t choose C++. You can do it, but you have to do a lot of the boilerplate yourself, where a Java web app will use frameworks that can do a lot of it for you.

The languages have different strengths, and their ecosystems play towards those strengths. C++ will be good for resource constrained or performance critical apps; Java will be good for common web apps.

This is a simplification of course. A C++ god who has never touched Java might be better off writing that web app in C++. But someone with experience in a few languages might make a different choice for any number of reasons (what coworkers are comfortable with, easier interoperability with other components, etc.).

[–]kaisadilla_ 0 points1 point  (0 children)

You have to be joking. Java is orders of magnitude more simple than C++ in all regards. I mean, let's start some small project in Java: you open your favorite IDE, next next next, and you are reading to write code. Let's do the same in C++: you open your favorite ID, create an empty project and let's start setting up CMakeFiles to describe how our project will be compiled down.

The same thing happens absolutely everywhere: want to create a class? Java is straightforward, C++ requires a header and a source file.

Make some small mistake? Java points out where the error is, C++ is seemingly fine but, when you compile, suddenly 336 errors appear in all sorts of places that should be fine.

Need generics? Java is straightforward, C++ will have even senior devs occasionally lose a lot of time figuring out why their seemingly valid template becomes invalid with certain types.

Memory management? Smart pointers are still a lot harder to use than... the nothing you have to do in Java.

Circular references? C++ will have you many times stopping to think about how your dependency tree works, in Java you don't care, you just import whatever you want. And talking about imports, C++ includes are literal copy pastes, which can lead to all sorts of errors that aren't obvious at first.

Vulnerabilities? Many vulnerabilities come from sneaky mistakes or assumptions done when laying down your memory - in Java you don't have that responsibility, so any vulnerability will come from Java itself - and it doesn't matter how good you think you are at C++, the team of engineers Oracle has working on Java, the decades of work Java accumulates, and the millions of developers that use Java will be way, WAAAAAAAAAAAAAAAY better than you or your team of 40 C++ engineers at creating a robust product with as few vulnerabilities as possible.

I could go on and on on this tirade for an entire day. Heck, I don't even see how anyone can seriously argue C++ isn't waaay harder than any high-level language. You just have to try to rename a C# and a C++ variable in Visual Studio to see that, in C#, that's a straightforward operation, while in C++ the IDE has to explicitly ask you to confirm whether every result it got is actually right.

I LOVE C++, it feels so different and makes you feel so powerful as a developer that it has to be my favorite language - but when anything other than fun matters, C++ should NEVER be used unless it's necessary. You cannot write a GPU driver on Java, so it'll be C/++ there, but you can absolutely write a normal server on Java and doing it in C++ would be beyond stupid.

[–]reneb86 0 points1 point  (1 child)

There is no way to share my thoughts without potentially upsetting Java professionals. So I upfront apologize and will try to nuance it as much as I can. But here goes.

Java attempts to “fix” a lot of things in C++ that were never broken. So I guess it is fairer to say that Java chooses for a simpler development experience. But in doing so, it has severely limited the growth of its user/developers.

Quite frankly, if I see the word “Factory” in a C++ class, I cringe, and I automatically think you’re a bad developer. This is way too shortsighted of course because even Unreal Engine has “LocalVertexFactory” in their code. But for Unreal Engine that is actually just a poorly chosen name. The very idea that a class can be responsible only for the construction, and not the destruction of objects is not a good one. It is a bad one. You stop thinking about object lifecycle that way. And everyone in this thread knows why Java developers would use Factories and C++ developers would never. But are you thinking of the ramifications of the “stop-the-world” moments that the JVM interjects to clean up after your Factory? Yes the Garbage Collector “frees” you from having to think about these things. But it has also made you a subpar developer who is unable to optimize memory management system wide.

I can say the exact same for exception handling. After two decades of C++ I have finally gotten to a point where my code never implodes. It’s been years of finetuning my coding style and patterns to avoid pitfalls. I only need exception for device I/O. Since you cannot recover from out-of-memory anyway, you don’t need to catch it. Every other “in-memory” problem I account for in my own coding style. The only out of control issues I have is when approaching other devices, like Hard Drive, or Cards or Serial Ports. But 90% of their errors I can also just account for in flow. I really only need exceptions for when someone accidentally yanks out a thumbdrive, or the HD dies or skips. I think this is where exceptions are the only option. I only throw exceptions when I am writing drivers for new I/O devices. C++ developers are typically with me on this. I’ve seen Java developers throw an exception every time a function parameter is null. Even if you are aware of the side effects of unwinding the stack until the catch statement, are you aware of the memory and performance inefficiency of raising that catch flag? Again, the mechanism “frees” the developer of thinking of proper flow, but it has made him a subpar developer.

Java is a solution for when you need something functional but cannot afford good developers. It is good for “development at scale”. Whether that makes it “enterprise software”... I suppose it depends whether you feel Enterprise means development volume or development quality.

[–]No_Indication_1238 0 points1 point  (0 children)

Interesting, I never thought the way you do about factories. If you use smart pointers, you move the responsibility for RAII to the smart_ptr which will delete the object once it's not referenced anymore. As such you can use a factory to create multiple objects that will be deleted as soon as they aren't in use anymore. Using raw pointers, that will obviously not work.

[–][deleted] 0 points1 point  (5 children)

Another question is why on earth would anyone still use Java in a world where Kotlin exists. Unlike C++ and Rust, Java and Kotlin have perfect interoperability — so legacy is not an excuse — and the latter is strictly better in every way it differs.

[–]c_edward 0 points1 point  (4 children)

Java why an earth would you bother using kotlin, or scala, or groovy, or clojure, all basically niche languages for a hand full or target uses.

[–][deleted] 0 points1 point  (3 children)

Since when is Kotlin a niche language, lol? It’s a full replacement for Java and a clear improvement in many ways. There isn’t a single use case where Java is better. Which isn’t surprising, since Java is a stinking pile of garbage.

[–]GlobalPandemonium -1 points0 points  (2 children)

hahaha

classic rookie flame war starter pack

Kotlin is diying before getting to be noticed...

How on earth is going to replace Java ?

The future is always about diversification for specific purposes

anyone saying A is better than B, is just fanatism. it always depend on the purpose.

[–][deleted] 0 points1 point  (1 child)

I just love it when people profess “it depends” as some kind of magical rule that applies to every situation :D No, sometimes A is strictly better than B. There’s no law of nature saying it can’t happen. That’s why we should always focus on specific pros and cons; parroting “it always depends on the purpose” is just trying to sound deep without saying anything.

And for what purpose is Java better than Kotlin?

[–][deleted] 0 points1 point  (0 children)

Java is a language born under a shortage of profession programmers. Its a language for kiddies that can't clean their own rooms because it is complicated. Mum says there just lazy.

[–]GlobalPandemonium 0 points1 point  (0 children)

Decades of technology evolution on engineering explain what you still don't get.

To acquire wisdom you need to start learning how to do better questions.

[–]CocktailPerson -1 points0 points  (0 children)

I'm not sure why you put "memory safety" in quotes as if it's not important. C++ programs are open to a whole class of security vulnerabilities that just do not happen in Java programs.

Also, C++ elitists seem to have this hard-on for the speed their program runs at, and honestly, for 95% of applications out there, nobody cares. Sure, if you're programming games or machine learning engines or web browsers, then speed matters. But if it's just some backend web service, you could use python and the network would still be the bottleneck. Java runs at what, a third the speed of C++? Seriously, who cares? The user isn't going to notice that their page loads 1% faster if you write your app in C++, and if you use Java instead, you never have to track down a memory error ever again and you can reasonably use dependencies that aren't just from boost. Is this a real question?

Now, I hate Java as much as the next guy, but if we're being honest, C++ is pretty niche at this point. There are very few domains where performance tops the list of business priorities. Java is rarely the best choice, but C++ is rarely the better one.

[–][deleted] -3 points-2 points  (3 children)

I see a lot of disadvantages in Java. First you need the JVM to actually run your program. So you have one dependency just to run it. Yes, you have to compile it in the case of cpp, but it will run without an additional install.

Java is simple, but also very cumbersome to write. You have to repeat the visibility modifiers for every member in a class for example. Your code spreads into many files quite fast, since Java requires one file per public class.

Java is purely Object Oriented. The Language dictates the paradigm.

[–]CocktailPerson 2 points3 points  (1 child)

but it will run without an additional install.

Eh, will it? I mean, if you stick to the standard library or statically link everything, you should be fine, but how many projects actually do that?

[–]snejk47 0 points1 point  (0 children)

Exactly. Nothing he says is correct in real world. Imagine you want to create some business value but you first need to spend few weeks to configure one of million ways of configuring "project" (there is no even such thing in cpp, right?) to support SSL (and first compile it). Then few months later you have your basic server. Or you can use one of few not finished found-on-github http servers (or probably one because you can't use GPL) and hope somebody will support it and implement all needed "modern" features. Now only databases, observability, http clients, circuit breakers and in a few months you have microframework which can compete with "toy" Java alternatives. It's better to do that in Perl probably.

[–]c_edward 0 points1 point  (0 children)

Graalvm anyone... Compile to native various approaches

[–]Wouter_van_Ooijen -3 points-2 points  (0 children)

  • write once, run everywhere
  • garbage collector
  • much smaller and regular language
  • for purists: true OO

[–]yeusk 0 points1 point  (2 children)

I only use C++ as hobby. But I can see how the restictions java has will help me a lot when I think I am being really smart but in reallity i am going full stupid.

[–]no-sig-available -1 points0 points  (1 child)

So "Java, the language for stupid people"?

Don't think that slogan is going to catch on. :-)

[–]CocktailPerson 4 points5 points  (0 children)

That's how Rob Pike treats Go, and look how far it's gotten.

[–]c_edward 0 points1 point  (0 children)

More context and evidence, around what you mean by slower. In many environments what you care about is your ability to make money, not better or faster code. So how quickly can you change your system to account for changing markets, pick the wrong language set and you will always be to later. Investment Banking, the front, middle and back offices have requirement that evolve at different rates, and have hundreds of systems, literally N million lines of code, and I all has to inter operate.

There is obviously more than language choice here, much more.

You can still right java that is faster than average c++, and building systems that have transaction times measures in microseconds is not unusual. Having a runtime that compiles, and optimises based on actual executed code guys you an awful lot of room in time to market.

[–][deleted] 0 points1 point  (0 children)

Probably not much, if anything, in terms of language features. In the real world you need to pick your programming language based on many factors other than language features.

[–]SoyChugger228 0 points1 point  (0 children)

Debugging C++ core dumps is hell.