4 ms·
In my experience, the most ergonomic implementation is rarely the most performant one in C++, you usually end up having to use some SFINAE monstrosity or sprink
by spoiler 5y ago
In my experience, the most ergonomic implementation is rarely the most performant one in C++, you usually end up having to use some SFINAE monstrosity or sprinkle constexpr if all over the place. std::optional comes specifically to mind as one of the big offenders here.
You've also gotta be careful with unexpected and implicit assignment/copy/move constructors.
More than half of all the C++ wisdom one needs in their career is when to avoid stdlib and which part of boost to use. Due to C++s religious devition to 80s compatibility, it becomes a minefield of a Don'ts, with a narrow path of Dos.
The fact boost is a billion libraries in one speaks in of itself about the abysmal dependency situation in C++. There's also a buncha dep managers that are at each others throats. Also, C++ people like to poke fun about js devs and npm/leftpad, but forget that they use boost for even more rudimentary string operations. Or they implement the same thing over and over again. Or my favourite: copy+paste the same code in multiple projects, and then have divergent implementations of the same thing with different bugs and/or API surface; bonus points if the thing is part of an RPC implementation.
As much as the edgy-dev crowd loves to belittle the very concept of dependency management, at least JS/Ruby/Python ecosystems give a shit about DX and made sure the package managers can be used with the same repositories/sources.
But hey, at least C++’s IO is buffered by default. Amazing.
I got distracted by my rant above: I actually PREFER the default is unbuffered, because it doesn't violate the principle of least surprise (if we remember that Rust is a systems programming language). The fact you expect the default to be buffered is probably due to exposure to C/++.
- PaulDavisThe1st 5y ago> The fact boost is a billion libraries in one speaks in of itself about the abysmal dependency situation in C++. There's also a buncha dep managers that are at each others throats. There are no dep managers for C++ that have any kind of universality to them. To reiterate for the umpteenth time: many C and C++ libraries come with compile-time flags that totally change the nature of the resulting library. It is not possible to refer to a "canonical" version of the library the way you could with something for Java, Python, JS etc. When I say "this code relies on libfoo", it is necessary to know if there are build/compile flags for libfoo that could change the nature of libfoo.{a,so}. If there are not (common, but not universal), great. If there is just one, probably manageable. If there is more than one, game over. Also, only C++ iostreams are buffered by default. Just like in C, where you are free do IO with syscalls if that floats your boat. There's nothing more or less obvious about this than in C, where stdio vs. syscalls is an essentially identical choice.
- duped 5y ago> To reiterate for the umpteenth time: many C and C++ libraries come with compile-time flags that totally change the nature of the resulting library. It is not possible to refer to a "canonical" version of the library the way you could with something for Java, Python, JS etc. That just iterates GP's point: C/C++ dependency management is abysmal, but it's "hard" because the languages themselves do not have the capability to express the required metadata in any standard way. As an example, the first time I tried to compile Ardour took me several hours finding and installing the right dependencies for my distro. PL designers have learned from these mistakes, it's not worth defending them or accepting that it is the way the world should be...
- PaulDavisThe1st 5y ago> but it's "hard" because the languages themselves do not have the capability to express the required metadata in any standard way. Of course the languages don't. It's not a part of the language. If I build libfoo with -Dexclude_feature_bar which just drops 2 source modules from the library build, how can the language express that? On Debian, you get the Ardour dependencies like this: apt-get build-dep ardour6 If your distro makes it hard than that, that's a distro problem. Of course, the libraries Debian or any other distro will install when you do that are not the ones we use to build Ardour, because we have patches for several libraries that will never be accepted upstream but are necessary/useful/important for Ardour. You can't express that with the language either.
- spoiler 5y agoI think you and the previous poster are talking about the same thing. I think they are pointing out that there's no way to express (I guess there is via macros, but it's a workaround) this, whereas it's innate to Cargo and Rust.
- PaulDavisThe1st 5y agoIt cannot be innate to any language because I may wish to link libraries written in other languages. You cannot use Cargo or Rust to describe how a C or C++ library was compiled and linked.