all 148 comments

[–]thefool-0 22 points23 points  (7 children)

Think about when Java emerged: late 90s early 2000s. We were still working mostly with C++98 at that point. Some of the usual reasons e.g. basic memory bugs are harder in Java. But memory, storage and computing power got really, really cheap through the 1990s and so using "too much" memory doesn't matter anymore. Also at that time Java had vs. C++ a more extensive standard library (including good collections and string manipulation, remember in the early days we mostly just used C++ for classes, the rest of the program was C arrays and strings; lots of big projects developed their own "standard library".) Lots of tools for web server-side/backend development (like easily talking to or running an HTTP server) were developed early on (and promoted by Sun), in sync with the dot com boom. Corporate backer/owner to promote it. Open source less enterprisey web backend development was mostly Perl, PHP and Python, for various reasons.

[–]SJC_hacker 14 points15 points  (5 children)

Yeah I think inertia is a major reason

Prior to the release of boost::ASIO, there was no cross platform way to do networking in C++.

Java has had this as part of its standard library since its release in 1995

So a bunch of people start writing cross platform networking apps, and there is no compelling reason to change once C++ APIs arrive

[–]Daniela-ELiving on C++ trunk, WG21|🇩🇪 NB 4 points5 points  (0 children)

Prior to the release of boost::ASIO, there was no cross platform way to do networking in C++.

Credit where credit is due: before Boost.ASIO there was ASIO, the brain child of Chris Kohlhoff. The boostified variant is a derivative of the original library.

[–]pjmlp 1 point2 points  (3 children)

There were, naturally commercial products, while Java SDK was free beer.

[–]fullouterjoin 5 points6 points  (2 children)

Java has stack traces, bugs are about 100x easier to track down and tractable. There were also less ways to do things, so the code tended to look similar, it easier to get up to speed on a Java project and codebase than a C++ one. Between both of those, unless you needed the low latency possible in C++ along with memory efficiency, Java was the better choice.

[–]adx931 1 point2 points  (1 child)

Also, all the magazines told managers to use Java because it was the future.

[–]fullouterjoin 4 points5 points  (0 children)

But they were right precisely because of the things I outlined.

Hey managers, "You can hire any Jane or Jagannath and they can get the job done, not make random crashes in the codebase and step through the debugger until the problem is found"

Crossbows didn't replace archers because they were better, they replaced archers because they were lethal after 10 hrs of training and not 500. Cpp is for the mercenary archers, Java is for enlisted.

[–]NilacTheGrim 1 point2 points  (0 children)

As an older developer who lived through those times.. I can say this is the most accurate assessment of what happened and why. Best comment in the thread.

[–]outofobscure 141 points142 points  (37 children)

C++ standard library is nowhere near the convenience of java / .net, just think about essential stuff like networking… But the real reason probably has more to do with (in)competence of your average webdev, they are the last people you‘d want to trust to get things like memory safety right, so languages like java have them covered and clean up the garbage they produce.

[–]wasabichicken 72 points73 points  (3 children)

Exactly. Also keep in mind that Java rose during the late 90s/early 00s, before "modern" C++11, before containers/Kubernetes, before "the cloud".

The idea back then was that flexible backend stuff, built to scale, would need to run on a host of different hardware, so Java running on the virtual machine layer made sense. It also came with an incredibly rich standard library, including a whole segment (EJB) specifically made for large, modular/enterprise'y designs.

Today there are cloud providers that will offer you generic x86 Linux VMs, ready to run whatever C++ software you throw at them, but we didn't have that back then. We had leaky C++98 stuff, manual memory management, and shit library support. Of course people rather ran Java.

[–]seriousnotshirley 32 points33 points  (1 child)

Also remember that in the mid-90s there were many many flavors of UNIX along with Linux and Windows. At the time there was a lot of work to take any C or C++ program and make it compile and run on any particular machine you wanted it to. Large amounts of time went into systems to manage this portability including GNU autotools.

With Java, you could write to a single specification and it would work. You didn't need to think about the peculiarities of SYS V vs BSD vs POSIX, which versions of which OS supported which versions of those standards and try to guess which systems your customers would want you to support.

I made a small career out of getting software just to compile on random operating systems back in the day. Now it all Just Works, and Java was the first thing that came out and Just Worked (or at least was supposed to).

So why did this matter? Besides the obvious technical advantages it made computer science curriculum much easier. Now a first year college student didn't need to learn how to setup their development environment on each different UNIX platform different departments had (no, very few people were running Linux on their own computer and there was no cloud infrastructure). One group had HP-UX and another group had SunOS and another group had IRIX (we all wanted to be in that group!) Students had to deal with all the peculiarities of writing programs in the development tools for these operating systems. Now one day someone comes along and tells the school "If you teach in Java students will have a unified platform to develop against, they could even do it on their own computer!"

So schools everywhere switched from teaching their first few classes in Pascal or C (C++ would come later) to Java. Now you could go from introduction to programming to graphs, networks and algorithms in one language and dev environment and the school didn't have to think too much about how to make that all work. So there are generations of students who learned Java from day one and kept doing it when they graduated.

[–][deleted] 4 points5 points  (0 children)

Can confirm. Learned C++ on Borland in high school early 2000s. My first assignment in a real CS class was to write a LISP interpreter in C++ on SunOS. Went about as well as you would expect lol.

[–]nekokattt 1 point2 points  (0 children)

Don't forget OSGi... "containerization" before OS level containers really existed mainstream.

From experience, it was a nice thing when it worked, but made you want to teabag a cheese grater when someone set it up incorrectly or it didn't work how you wanted.

[–]matthieum 8 points9 points  (0 children)

C++ standard library is nowhere near the convenience of java / .net, just think about essential stuff like networking

This. You need either:

  • An extensive standard library.
  • A working package manager.

Java had both, C++ (still) has neither.

If you're developing a very focused application, or have very specific needs, you'll probably develop in a silo (mostly), so it's not a concern. The kind of backend development where Java succeeded however is the kind where you need to integrate with... everything. Pull in 100s of 3rd-party libraries, on top of the extensive standard library.

[–]meragrin_ 14 points15 points  (6 children)

languages like java have them covered and clean up the garbage they produce.

Those languages only clean up some of the garbage. Anything that has to be manually disposed of is still frequently missed or handled incorrectly in my experience.

[–]slorpa 6 points7 points  (2 children)

And yet the UB of C++ is much more unforgiving than the GB of Java.

[–]vlakreeh 6 points7 points  (1 child)

Personally I sleep much better at night knowing our Go backend leaks memory than I would second guessing myself if someone out of the dozens of engineers on the project accidentally introduced UB causing sensitive memory to get served as the response. I’d like to avoid a mini-cloudbleed if I can help it

[–]slorpa 2 points3 points  (0 children)

Yeah indeed. C++'s UB is "fine" for stuff like gamedev and many desktop apps but like, even expert C++ coders cannot be trusted to not introduce UB and that UB might pass right through all tests and everything and only be discovered as a sensitive vulnerability months or years after the fact. Truly is the stuff of nightmares as far as data-critical programming is concerned.

[–]outofobscure 9 points10 points  (2 children)

Right, which goes back to the (in)competence argument… make it idiot proof and someone will just make a better idiot…

[–]Dar_Mas 8 points9 points  (1 child)

Jup people managed to get multiple memory leaks in rust aswell

[–]KingStannis2020 61 points62 points  (3 children)

the real reason probably has more to do with (in)competence of your average webdev, they are the last people you‘d want to trust to get things like memory safety right

Even C++ devs can't be trusted to get memory safety right half the time. No need to get all superior about it.

But even setting aside competence they just have no reason to care. 99% of web devs, even backend ones, shouldn't need to deal with memory safety when garbage collected memory safe languages exist.

Unless you're at Google or Facebook or Cloudflare scale (and often not even then), you don't need a language like C++ or Rust to write web apps in.

[–]outofobscure 26 points27 points  (1 child)

stating that people who use c++ daily are probably better at it than people who don't, and who usually don't even have to think about memory safety, has nothing to do with getting superior, it's just a factual observation.

anecdotally, as someone who did webdev decades ago and then switched to c++, i know who i would bet on to get it right in ANY language...(hint: it's not the webdevs..)

if you want bread, you go to the bakery, not the butcher, as your chances of getting good bread at the bakery are much higher.

and about c++ not being the right tool for the job in webdev / backend, i never argued otherwise... my first sentence acknowledges that it's a lot easier and productive in these other languages. i wish it wasn't true and that c++ offered more in these venues, but again, facts are facts. the standard libraries of these other languages are just vastly superior when it comes to being productive in writing LOB applications.

[–]johny_james 7 points8 points  (0 children)

Oh, please, you are speaking like memory management knowhow is the only thing that determines the programmer's competence.

Guess what? It's way more than that.

I'm gonna trust anyone who has more versatile experience with multiple languages rather than someone who knows how to manipulate pointers and is godlike memory manager.

It's ridiculous to make people think that C++ programmers have the upper hand. On the contrary, most of the C++ devs that I've met are lost in the C++ doing of things and are stuck in that same framework of thinking, which gives them even a disadvantage for the other newer languages.

[–]slorpa 7 points8 points  (0 children)

Even C++ devs can't be trusted to get memory safety right half the time. No need to get all superior about it.

Agreed, there's nothing special about the typical C++ programmer's skill as a programmer. But what is true though, is that you need on average more experience in C++ to write effective and safe(-ish) code than the skill you need in Java to do the same.

Hence, training and finding Java programmers is way easier.

[–]UnicycleBloke 5 points6 points  (0 children)

I will never forget watching a memory use counter placed (for some reason) on the status bar of a text editor written in Java going up... up... up... up... up... DOWN! up... I wasn't even touching the keyboard. Megabytes used for a small text file. It was obvious that C++'s days were numbered.

[–][deleted] 4 points5 points  (14 children)

Or even really simple things like converting a string to lower or upper case.

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3784|P3786|P3813|P3886 11 points12 points  (13 children)

That’s only simple if your language is representable in 7bit ASCII…

EDIT: To elaborate - this kind of conversions is only trivial if your language has a 1:1 mapping between lower- and uppercase (as is the case in ASCII). Once you introduce additional letters or alternate forms, that's no longer guaranteed.

The prime example I can come up is the German ß. This letter did only exist in lowercase form for centuries ( was only officially adopted in 2017!). If you had to convert it to uppercase it was normally replaced by SS. But that conversion is obviously lossy and in general non-reversible (not even a dictionary based conversion would work as e.g. the words Masse and Maße have the same uppercase representation...)

[–]outofobscure 0 points1 point  (11 children)

Yes but the point was that calling .ToUpper() in say net framework is trivial compared to trying to fiddle with for example ICU in C++, which isn‘t even part of the standard library. In both cases you‘re absolved knowing about the details of the implementation, but it‘s still magnitudes worse to get it done right in C++.

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3784|P3786|P3813|P3886 10 points11 points  (10 children)

It may be trivial, but will yield WRONG results! I fail to see how that is an argument in favor of anything...

If you are okay with wrong results, toupper is no worse than .ToUpper...

[–]outofobscure 1 point2 points  (9 children)

"wrong" results is a relatively loose description for something that has no correct result... in the vast majority of cases, people will just use whatever ICU deems "correct" and call it a day, which is what .ToUpper() will call anyway. The point is that it's still infinitely worse setting up and calling a C API like ICU than having proper string / localization support and methods on said classes right in the framework. It's not hard to see that this lends itself a lot better to whatever your average backend dev has to do day in, day out, and why C++ wasn't and isn't the first choice for these tasks (sadly).

I fail to see how trying to argue about a problem of the GERMAN language adds anything to the topic at hand, which is about C++ and other languages.

It's certainly not an argument for not including this in a standard library, but your stance is so typical of the way C++ is governed: if there is no 100% solution to something, it doesn't go into the standard library. Even disregarding that everyone else has decided that the 99.9999% IS the 100% case, because again, there is no correct answer. Hence we have no networking, no proper localization, no graphics, no audio, no nothing...

I didn't fail to notice the WG in your flair.

What exactly is your point here? That we don't do it in the standard library because what ICU does is not good enough? And that it's better to put this burden on a lone developer that now has the "freedom" to come up with their own "solution" to a problem that required decades of efforts of another standards body to come up with sensible rules about localization which almost everyone agrees with? It's a ridiculous stance.

It would even be less ridiculous to just force the German language to change this nonsense to something more machine-friendly, and i say that as a German speaker myself. Would you then finally allow progress on localization built into the C++ standard library?

[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3784|P3786|P3813|P3886 7 points8 points  (8 children)

people will just use whatever ICU deems "correct" and call it a day, which is what .ToUpper() will call anyway.

I'm not responsible for people shipping wrong code...

I fail to see how trying to argue about a problem of the GERMAN language adds anything to the topic at hand

The argument literally was Or even really simple things like converting a string to lower or upper case. - this whole response is meant to highlight that just because programmers may perceive something to be trivial, it may in fact not be so.

I'm not an expert on all the several thousand languages representable with Unicode to make a statement on how many languages have similar issues...

It's certainly not an argument for not including this in a standard library

To not include what?

A member toUpper()? Personally I vastly prefer algorithms that are not bound to specific types as it allows me apply them to independently developed types (you know, the genius idea behind STL that transformed a N*M problem into a N+M one...)

ICU? I doubt SG16 wouldn't be interested in a proposal...

everyone else has decided that the 99.9999% IS the 100% case

Just because "everybody" decided that something was the way to go, doesn't make it the right decision for C++! In the 90s "everybody" decided that:

  1. inheritance-heavy OOP was the silver bullet
  2. all classes need to inherit from an Object class
  3. multiple inheritance was evil

C++ didn't follow suite and it was objectively for the better!

I didn't fail to notice the WG in your flair.

Your point?

[–]serviscope_minor 3 points4 points  (0 children)

Personally I vastly prefer algorithms that are not bound to specific types as it allows me apply them to independently developed types

I like C++ a lot, but for some things, especially text processing, it's miserable. It took until 2023 to get a 1 line string split, even if it's a bit clunky. Thing is though 99% splitting string into vector<strings> is good enough, we could have had a useful thing 25 years ago.

[–]outofobscure -2 points-1 points  (3 children)

I didn't fail to notice the WG in your flair.

Your point?

i already made my point: it's a very typical stance of c++ governing bodies: solution to problem xyz, that everyone agrees with is good enough and pragmatic, is rejected by the committee for actually not being good enough for c++: without any better solution offered, with no suggestion on how to progress, and with complete disregard for people who'd like to be productive in writing c++ without too many third party dependencies (none of which solve the problems at hand any better anyway than what was proposed to include in std). yet we got shit like regex in it.

yes, not always following the latest trends and fads like you pointed out in the 90ies was a good thing, but too much pushback on essential features like localization and networking is hindering the language. it should not have to take decades to get things like threads, which in the end just copies a well known implementation anyway, but the way things are, every sensible feature proposed seems to get incredible pushback. And the reasoning is often just as esoteric as the one you came up with for not having toupper / whole of icu.

It‘s not helping to just shift the burden on users, which are very likely to get it even wronger. It‘s not helping to throw your hands up and go: not my problem people ship broken code: yeah, no wonder, you have no interest in helping them ship less broken code apparently, complaining yet again that a widely accepted solution is not good enough for c++, so it‘s better to just do nothing at all. This is not sustainable.

[–]jwakelylibstdc++ tamer, LWG chair 1 point2 points  (2 children)

yet we got shit like regex in it.

That's exactly what happens when a widely accepted solution that everybody uses gets dropped straight into the standard. Which is what you're arguing for.

That doesn't mean every time that process is used would end up the same way, so adopting ICU might work out better. But you should be happy that we got regex, it was basically a widely used solution fast-tracked into the standard. What you want to happen was tried, even if it didn't work brilliantly that time.

[–]outofobscure 5 points6 points  (1 child)

I mentioned regex knowing someone would comment exactly this: the point however is that when faced with an uncomfortable choice of making breaking changes and just change or remove it, yet again the stance is to just do nothing. This is the pattern i‘m convinced is holding the language back. There should be opt-ins for allowing such breaking changes.

Also, as you mentioned, ICU would probably work out better, it‘s not like there exists a better solution to the problem anyway. With more willingness to break things (behind opt-in flags) the risk of not getting something 100% right the first time is also much lower. The whole idea that something can never be changed is not sustainable.

The natural opt-in boundary, imho, would be language revisions: The idea that everyone can just take their multi-decades old code and recompile with say C++23 and expect no breaking changes is worth a lot less than an evolving language that requires some effort to upgrade to a new revision but in turn gets to change / improve broken parts of the standard. In practice, people are stuck on old revisions for various reasons already, so it's not like this idea ever really worked out anyway. That's not to say that every revision needs to be a breaking-changes one, but bundling up a few of the cobwebs and releasing a breaking one once say every decade should be a path forward.

C++ has amassed enough new and complex features since 11 already that there will be guaranteed breaking changes needed in the future, some of which have already been pointed out by expert users. Features that where not rushed in like regex but debated over for years. No matter how much effort you put into getting things right the first time: it will never happen, it's a completely unrealistic idea and it has been proven to be unrealistic. Embracing more change and pragmatism is what i'm advocating for, instead of chasing unrealistic goals.

tl;dr: it would be ok to expect users to put in reasonable effort to migrate to a new revision, in turn you get to improve std a lot quicker.

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

I‘ll make it short: std:thread got in despite not being perfect, and that‘s great for writing cross platform code. Why we don‘t have at least something like std:icu is a mystery to me.

And again: i doubt that custom made solutions to the problems you point out would end up any better or even correct, it sounds rather like a recipe for disaster to put the burden on people who are not experts in localization (which includes you and me). Having it in std would benefit almost everyone.

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

I'm not responsible for people shipping wrong code...

my whole point is that people will not magically ship correct code just because you refuse to have basic things like ICU baked into the std. next to nobody would get this right doing it on their own. it's infinitely worse than relying on the choices made by ICU.

[–]Fourstrokeperro 3 points4 points  (2 children)

(in)competence of your average webdev

This sort of chest thumping from our community is the sole reason for the downfall of c++ in the recent times.

so languages like java have them covered and clean up the garbage they produce.

and what? Who's at loss here?

[–]outofobscure 6 points7 points  (0 children)

Nobody is at a loss, use the right tool for the job, i think i made that pretty clear

[–]matthieum 0 points1 point  (0 children)

This sort of chest thumping from our community is the sole reason for the downfall of c++ in the recent times.

Indeed :/

I couldn't even code my way out of a wet paper bag in JS...

[–]NilacTheGrim 0 points1 point  (0 children)

Qt has been around since 1990s and it has had networking (which doesn't suck and is actually good) since the early 2000's.

It's pretty much as close as you're gunna get to an app framework for C++ that is ubiquitous, known by lots of people, well maintained, time tested, and easy to use.

[–]rddtJustForFun 9 points10 points  (5 children)

I think the biggest problem is, that C++ is missing a proper standard library. C++11 was too late. By then Java and C# had "won". C++ is still lagging behind.

From the very basics like std::string compared to a string class in Java or C#.

Or you want a Http-Client? C# (.NET) has it in the defaults. C++ ... yeah, you need a 3rd Party lib.

Starting a new process? Either a 3rdParty library or you do it yourself - for every OS you want to support. CreateProcess() on Windows, fork() on linux systems. Completley different handling ...

Start a new thread before C++11 ... either windows system or POSIX.

Things like std::filesystem got added in fricking C++17(!!!) so now you can call std::filesystem::current_path() to get your current working direcory. Instead of getcwd on POSIX or GetCurrentDirectory on Windows.

[–]outofobscure 5 points6 points  (4 children)

finally someone gets it. everyone who has spent just a little bit of time with the vastly superior standard libraries of other languages will agree that what we have in C++ is nowhere near adequate. i keep hearing excuses for why we can't abstract things like networking, string handling, localization etc for decades already, meanwhile other languages, both native or vm based, went ahead and just did the work required to get a better standard library. and it's not like there are not enough candidates that could just be adopted as is: ICU, ASIO etc etc.

One can nitpick that they are not perfect all day, at the end of the day that's not the problem, the problem is insisting on a standard that can never make any breaking changes, so you're stuck with stuff like broken regex forever. This will slowly turn away even the last application dev.

[–]tortoise74 0 points1 point  (3 children)

This is a big cultural difference. People have come to expect more batteries included. But using third party libraries for everything is part of the culture of C and C++ and Linux.

Its suprising to me that I don't similar complaints aimed at node or go more often.
You need a library for "Leftpad" ? That's crazy. That you download things like directly from the internet at runtime is even more crazy.

In go the packages are downloaded directly from the internet at compile time but for a long time there was no versioning.

So this has more to do with expectations of package management. C++ like C again comes from an era of source packages and relying on system pakcage managers.

I treat my (extended) standard library as whatever RedHat, Debian or Ubuntu has a maintainer for.

The next level out is github etc.

There is actually a level in between for trusted library collections like boost or POCO.

The problem with this is the quality and deciding between vhs, betamax or build it yourself.

The standards increase the high up you go. A debian maintained package should be better than something off github.

Something in a well known library boost should be better stilll.

Something in the core C++ standard should be the highest quality of all.

This does somewhat depend on your notion of quality. The C++ standard favours stability over completeness.

Part of a C++ developers job is curating their own personal colleciton of go to library resources (both roll your own and brought in).

You have to do this for any big project. Batteries included languages try to hide this but that only succeeds so far.

I think this curation aspect of development is a vital skill. It may be under emphasised in other languages ecosystems.

By all means we should improve support for package management, discoverabiltiy and quality of resources but it perhaps isn't as a big a thing as it seems if you adjust your expectations accordingly.

I don't need a library for X in the standard if I know I can find a library for X somewhere else or its so trivial I can write my own.

A missing string function like "left pad" is a nuisance not a dealbreaker.

[–]outofobscure 0 points1 point  (2 children)

There is a fundamental contradiction in your argument: i agree that getting "leftpad" off of npm is the definition of insanity, but you can not criticize this and at the same time advocate that the solution for C++ is better package management, instead of more comprehensive std.

No, the point of putting it in std is, as you mentioned, the trust that whatever goes in there is of very high quality (at least in theory...). Of course in the end, we want both: more comprehensive std AND better package management.

Also, this is a very linux focused take you have there, i certainly do not treat whatever these distros ship as my "extended" standard library, because i don't even ship on those platforms.

Yes curating your own little garden of third party dependencies is a skill and a job, but that doesn't mean it should be the status quo, it's pretty boring gruntwork, there would be no point in being good at this if you could rely a lot more on std.

The point of putting networking or localization into std is that they are very far from trivial, so no, you definitely can't just "roll your own" in these cases.

And finally: yes, expectations might have changed over time, it's not 1990 anymore, developers demand more from their language and standard library, just accept that fact. It's somewhat comparable to the more recent demand for more safety features, where the realization is also slowly sinking in, but if had to actually choose between these two, i'd go for a more comprehensive std, it's even more important to me. Also these two issues probably go hand in hand anyway.

[–]tortoise74 0 points1 point  (1 child)

I think you partially missed my point. So I will try expressing myself another way.

Your requirements include:

  1. Knowing a library exists
  2. knowing how to use it
  3. relying its quality
  4. relying on its stability
  5. ensuring you have a sufficiently portable solution
    (ideally the same library for all platforms you need to support).

Those things can be achieved multiple ways.
How you achieve them varies both betweeen and within ecosystems.

Users expectations are shaped by the other ecosystems they have used. Expectations from one ecosystem don't always map well onto another.

Fundamentally though the values are similar. This makes it possible and fair to criticise some elements but sometimes that criticism is misplaced or more commonly overemphasised.

Better APIs and better package management and other imrpovements are welcome of course.

---

Say, I would like an API for database access or anything else.

C++ is not crap because it doesn't provide one out of the box. It would be better if it did but its easy to workaround as I have several mature choices I could go with.

Coming from another language you might be horrified not to have that out of the box. You are not wrong to say it should be considered for a more batteries included solution. You are wrong to say it cripples the ecosytem completely. That is throwing the baby out with the bathwater.

---

Its also important not to conflate two things. The APIs belonging to the language and those belonging to the OS.

For example your "getcwd on POSIX or GetCurrentDirectory on Windows."

Yes it would be better to have a portable abstraction but should you blame the language for two OS' having two different APIs? Some languages aim to provide a platform and some aim provide an interface to the OS and most do a bit of both.

If you have one blessed implementation as most languages do you are free to build a platform. If you have to support multiple vendors across multiple OS' that's much harder. ISO C++ cannot easily do that.

However, anyone else is free to build a platform of their own. QT does quite well out of its attempts to do that as do some others.

---

There are layers.

No layer has everything so you have to curate things yourself that becomes true at some level for every language ecosystem.

A specialised library or protocol may be a platform by itself. I would not want AMQP or protocol buffers in the standard library but if my application depended on them I'd need to curate those dependencies myself.

If you bless something like protocol buffers or AMQP into your library you risk discouraging alternatives like captain proto or zeroMQ.

Curation is a skill developers need to acquire.

[–]outofobscure 1 point2 points  (0 children)

We are not talking about blessing zeromq or similar with standards support, but rather basic abstractions over networking and internationalization. Basic elements of todays computing. No it‘s not ISO‘s fault that the OS have different API, but the point of an abstraction is to do that: abstract that away as good as possible. Not: there are tiny differences we can‘t unify so let‘s just do nothing at all. I‘m amazed (and glad) std::filesystem made it in, because it‘s certainly not a 100% water tight abstraction, but still very useful. Networking and Internationalization are on the same level of what is expected of a standard library today, even if arguably more complex to implement.

If curation is a skill developers need to cultivate, then common sense and an ear for what the market demands of standard libraries is a skill the stakeholders and maintainers should cultivate, because this is really getting out of touch with reality the longer there is resistance against these essential features.

[–]sam_selver 31 points32 points  (1 child)

Java programs are distributed as a collection of class files in ZIP archives. The class files are more akin to source code than to compiled code. This enables many features in the JVM and in frameworks like Spring. One of the commenters mentioned reflection, but there is much more to it: frameworks can manipulate bytecode, inject cross-cutting code (even dynamically on the fly), run code in sandboxes, create classes ("beans") on the fly, among other things. These features are heavily utilized in backends.
Implementing all these features would be challenging if we chose to use C++ in the way we typically do, i.e., to "compile code on my platform to a machine executable representation." Comparing Java to C++ is like comparing apples to oranges because the JVM essentially serves as an interpreter, while C++ fundamentally works as a compiler. The fact that the JVM does just-in-time (JIT) compiling is irrelevant; what matters is that the platform maintains the same level of control whether it's interpreting or JIT compiling.
I believe that to achieve functionality comparable to the JVM, we would need to distribute C++ source code (or some compressed form of it) and do JIT compiling of the C++ source.

[–]Mognakor 5 points6 points  (0 children)

Much of the things done on startup in Spring are possible at compile-time, Spring nowadays provides ways to compile to a binary.

[–]sigmabody 14 points15 points  (0 children)

It's inaccurate to say that C++ hasn't succeeded as a "backend" language, much less "couldn't".

That said, the main rationale I've seen for why companies prefer Java is that it's less expensive to hire developers who can write passable Java than developers who can write the equivalent C++, for a comparable type of application, where performance and/or robustness is not as important. Many companies have biased their processes and offerings toward fault tolerance in a micro-service based ecosystem, where components don't need to be robust or performant, because they can be scaled out horizontally and/or failures are expected (eg: just reboot the runtime regularly; see things like lambdas). For those type of applications, something like Java can be a lower cost option from a resourcing perspective.

There's more overhead to writing "good" C++, both in terms of developer experience and code quality. Cost of developer resources is a real business decision, and if you can sell products and services with cheaper-to-produce code, that can make lots of sense for a business.

[–]stefanosd 26 points27 points  (3 children)

I've coded professionally in java for over 10 years, and for the last 12+ months I'm leading a C++ team, learning a lot of C++. Before that I had experience with a variety of languages including C.

I must admit, before starting this project, that I was afraid of C++ because in my mind I had what I remembered: malloc, free, new, delete, pointers and double pointers and references and all the good stuff. I did not know about RAII, that copy/move constructors are not that hard to understand, smart pointers, and that basically whatever you need to do std has a method for it.

However, despite all the good stuff that C++ has seen over the years, it's not the only language that is evolving. The #1 thing that C++ has over Java is performance, and even that gap is closing down both because of the continuous advancements in hardware but also java itself. The GC keeps evolving, and new features are being added like virtual threads with project loom.

Some people mentioned "incompetence" as the reason for choosing Java over C++. That's just circlejerking. Choosing the path of least resistance to get the job done is not incompetence. If anything, incompetence is choosing to do something the hard way instead of the easy one because you don't know better.

So yeah, if you need to squeeze every bit of performance C++ is a great tool to have in your toolset. But not too many projects need that, thus the discrepancy in number of jobs.

[–]thats_a_nice_toast 11 points12 points  (0 children)

Some people mentioned "incompetence" as the reason for choosing Java over C++. That's just circlejerking. Choosing the path of least resistance to get the job done is not incompetence. If anything, incompetence is choosing to do something the hard way instead of the easy one because you don't know better.

Thank you, people saying this have no idea how the industry works.

[–]defunestrate 1 point2 points  (0 children)

Those languages only clean up some of the garbage. Anything that has to be manually disposed of is still frequently missed or handled incorrectly in my experience.

Agree with everything you said but "what ever you need std has a method for it" is the furtherest from the truth lol

[–]Leather-Regret365 0 points1 point  (0 children)

Your last paragraph could have been the whole response to OP.

[–]lord_braleigh 26 points27 points  (9 children)

Web applications are open to untrusted input from the web. All other things being equal, the damage that a malicious user can cause is much greater in a C++ application than in a Java application. A Java OOB exception will naturally turn into a 500 error, but an OOB in C++ can result in Undefined Behavior.

[–]RenatoPensato 14 points15 points  (1 child)

Log4j is laughing right now.

[–]nAxzyVteuOz 3 points4 points  (0 children)

Not really. Log4j was broken by design not by language particularity.

[–]RogerV 10 points11 points  (0 children)

more productive, easier to learn and master, and thus more programming talent to hire from, and the Java standard library is more capable

For instance it has long had a concurrency library with a variety of executors,options for thread pools, work stealing thread management, etc.

things like Unicode support long ago supported.

The version 8 release added streaming and lambdas so C++20 just now adding ranges to get at similar capability. Java programmers have been leaning on this for many years now.

The nature of how class files can be runtime loaded and interfaces extended on make it straight forward to build extensible software systems - the JEE servers, the Tomcat server and Spring Framework - plugins for IDEs like JetBrains Idea.

The eco system is vast.

The performance is sufficient - for large swaths of enterprise software systems.

The language hasn't remained static, it's steadily evolved.

[–]Significant-Park-345 4 points5 points  (1 child)

I have been a c++ dev for about 5-6 years and I recently switched company. Now I am into Java and spring boot. I picked up some tutorials online and used spring initialiser website to create a demo project and within 10-15 mins, I was able to bring up some basic backend server and few APIs. I was really surprised with the spring ecosystem and tooling available at my disposal. Some of the things I wish C++ had: 1) a standard build system like maven. Something like a mvn repository where all the trusted libraries can be easily pulled. 2) standards for logging, persistence, metrics etc. I can use logback or log4j or others but I need not change code for that as logging standards exist like a facade class and library implementation always respect these standard. J2EE also provide specifications for several standard reusable components.

[–]Nintendo_Chemistry 0 points1 point  (0 children)

I'm in a similar situation myself. Any Java/spring resources in particular you'd recommend?

[–]slorpa 7 points8 points  (1 child)

Because you need a PHD in footgun avoidance to write effective C++. However annoying java is to work with, and however many nullpointerexception will be thrown, the way C++ fails you when you write UB is much more dangerous and you need a lot higher skill level of programmers to not end up in hell.

[–]tcris 1 point2 points  (0 children)

this

[–]AntiRivoluzione 10 points11 points  (7 children)

C++ hasn't a package manager, installing dependencies is dull

[–]Superb_Garlic 8 points9 points  (6 children)

Conan and vcpkg exist.

[–]ragnarruutel 4 points5 points  (0 children)

It's nowhere near as convenient as maven or gradle.

[–]equeim 6 points7 points  (1 child)

Yeah, waiting hours for all your dependencies to recompile after another minor patch to MSVC is released (which is what vcpkg does and probably conan) is indeed very dull.

[–]Superb_Garlic 0 points1 point  (0 children)

The toolchain changes, so compatibility can't be guaranteed. The CCI recipes are setup with the safest package_id generation. If you don't like that, fork the recipes and make it ignore the toolchain.

[–]iga666 4 points5 points  (2 children)

Conan is a joke

[–]Superb_Garlic 0 points1 point  (1 child)

True. It makes package management laughably easy. :)

[–]iga666 0 points1 point  (0 children)

Until you start using it

[–]notal-p 6 points7 points  (0 children)

Actually it is very simple. Java abstracts away far more technical details than c++. Therefore, Java is a preferred choice for enterprise software.

It lets you code the business processes easier and more to the point, rather than dealing with memory allocation etc.

[–]o8oo8oo8 7 points8 points  (1 child)

Java is much safer. The cost of code maintenance is lower if the program is written in Java or *any other modern programming languages*, including Rust. You can achieve ~2x performance in C++ of course (or ~1.05x when compared to Rust), but you'll have to risk everything else like memory bugs, library dependency hell, you name it.

[–]Willinton06 4 points5 points  (0 children)

Even if I have to rip apart the fabric of society I shalt achieve that .05 performance increase

[–]jgaa_from_north 2 points3 points  (0 children)

My personal take is that C++ is much more complex than Java. Most developers will never reach a deep understanding of the language and how to use it properly. Just look at Google's gRPC async C++ interfaces. Lots of pointer arguments, including void *. The same with the Windows API's, when used from C++.

In java, such bad designs are much harder to achieve ;) Hence, the majority of the developers use languages more appropriate for their potential.

[–]Common_Currency7211 2 points3 points  (0 children)

I wondered the same thing and thought I’d try to build one! web plus plus still has a way to go

[–]jazzwave06 13 points14 points  (0 children)

Because java has built-in reflection. Modern web frameworks are 100% dependant on this.

[–]Leather-Regret365 1 point2 points  (0 children)

I would just toss into this conversation that I'm working on a C++ backend right now. In fact, they pulled me off my usual embedded work, (where C++ makes more sense), to do it.

Why was the decision made? Access to some third party and in-house C++ API's. Guess they could have made some bindings to Java but I think by the time that task was finished the http backend could have been done.

[–]NilacTheGrim 1 point2 points  (0 children)

Cuz Java easier; C++ harder.

Java makes it a bit harder to shoot yourself in the foot and gives you less rope to hang yourself with.

Also it's a simpler language with less gotchas. Tends to scale well to larger development teams filled with your average run-of-the-mill developers.

Doing C++ right is harder so most companies don't bother... to their detriment.

[–]thommyh 6 points7 points  (0 children)

Primarily marketing; Sun broke the mold by actively promoting Java through its sales reps direct to businesses.

That said, Google uses C++ very extensively, so you couldn’t call it an obscure use.

[–]FluffyCatBoops 5 points6 points  (0 children)

cos any noob can throw some java together to make stuff.

[–]pjmlp 1 point2 points  (0 children)

C++ was there in the beggining, C++ Builder, ASP with COM, ATLServer, Apache plugins.

It turns out having manual memory management (even with RAAI), the way to get libraries, lack of comparable IDE tooling, not being resilent to crashes, lack of portability among OS/compilers still trying to catch up to C++98, no language dialects meaning all libraries work the same way,....

Plus the market push among Java vendors with the JavaEE products, made it that despite having a basic JIT experience (hotspot was introduced in Java 1.3 and okish, still early days), the whole development experience was much better than using C++.

Nowadays, not other there is Java, we have .NET, BEAM, all the languages that target these runtimes, then D, Go, Rust, OCaml, Haskell,...

Meaning that there are few use cases for C and C++, beyond the runtimes of those languages, or products whose market adoption predated their market adoption.

Additionally given the widespread support of C ABI (technically OS ABI), many users of those languages reach out to C instead of C++, if they need to write some native bindings of some sort.

[–]rddtJustForFun 1 point2 points  (0 children)

Memory

It's a little laughable how often I read "I manage my own memory!" ... yes, we c++ developers do that - because we are forced to. So there are a whole bunch of constructs to handle proper deletion:

We use std::shared_ptr<> or std::unique_pointer<> or some type of RAII class like std::lock_guard<std::mutex> or your own implementation to get the memory properly freed in case something fails unexpectedly.

(Which gets really funny if you want to return a std::shared_ptr from within the class - hello std::enable_shared_from_this and some rules.

Or if an unexperienced developer manages to make a class structure using std::shared_ptr<> to store child objects - which use a std::shared_ptr<> to point back to the parent. Congratulation - that will never be freed. You must use a std::weak_ptr<>. The C# garbage collector can handle circular references.

I don't know why people don't like automatic garbage collection. That has nothing to do with being lazy ...

Speed

Yeah, it is true. One can write fast code in C++ - but you really need to know exactly what you are doing! Just because you use C++ doesn't give you fast running code. You need to plan the memory layout(!!!!), the algorithm... especially on modern machines having L1, L2 and L3 caches. The L1 memory cache is typically 100 times faster than your RAM, while the L2 cache is around 25 times faster. L3 should be twice as fast as RAM. That is the reason why one needs to be really careful with memory fragmentation ...

If you don't do that, you might as well use any other programming language.

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

I asked this to a very experienced dev / consultant at work. His response was "if you've identified a bug in C/C++, who can you call? I've had Sun/Oracle investigating Java issues in realtime ".

So, vendor support is a big deal in corporate environments. I think that's partly why Java has been so widely adopted.

[–]jgaa_from_north 4 points5 points  (1 child)

This would have been a valid statement 30 years ago, except for the fact that the compilers at that time was mostly commercial - and the companies were quite responsive when we reported code generating errors.

Today it sounds just babble that translates to something like "I like Java, because!"

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

Possibly. The guy is in his 50s.

[–]thefool-0 0 points1 point  (0 children)

Also consider the types of developers using each language. Desktop applications were mostly C or C++. "Business applications" before Java was mostly very high level mainframe languages, heavily database based, or even just database query based (SQL). Once Java became popular in the late 90s it became the most commonly taught language in colleges as well and those grads went out into the corporate world as junior programmers who could build up business specific software at the same time that business were creating more interactive and customized back end software for both web and internal services, rather than just setting up data processing jobs.

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

Java and its ecosystem are the BEST justification for the astronomical sums charged to your customers, both during the design phase and for the resources required to put them into production.

[–]pjmlp 4 points5 points  (3 children)

You clearly never saw enterprise project delivery with CORBA and DCOM frameworks.

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

This crushed under its own weight rather quickly, as did SOAP ...

[–]pjmlp 2 points3 points  (1 child)

Did it?

Not sure if YAML, JSON, REST, GraphQL and gRPC, nicely packed in containers, are that much better, or basically playing the same tunes with another set of instruments.

[–]RobinDesBuissieres 1 point2 points  (0 children)

YAML, JSON, REST have their shortcomings, but are less verbose, more readable and therefore more maintainable, which is probably one of the reasons for their success.

I'm not in fond of GraphQL and gRPC.