3 ms·
I saw this this morning (and also rusts support for fmt strings). Whenever c++ is discussed I often find myself defending modern c++ against people who want to
by maccard 5y ago
I saw this this morning (and also rusts support for fmt strings). Whenever c++ is discussed I often find myself defending modern c++ against people who want to write c++03 because it's simpler. I like this article because it shows how useful modern features really are in practice.
- rixed 5y agoComplexity can solve issues but can also bring new ones. For instance, I've been bitten recently by the new "universal" syntax to write variable definitions with only curly braces. #include <iostream> #include <string> #include <vector> using namespace std; int main() { // Forty-two things: vector<string> v1 { 42, "foo" }; vector<int> v2 { 42, 1 }; vector<char> v3 { 42, 'x' }; cout << v1.size() << " " << v2.size() << " " << v3.size() << endl; return 0; } This prints, of course: > 42 2 2
- maccard 5y agouniversal initialization is the worst feature added to modern c++; these changes are unexcusable IMO.
- edflsafoiewq 5y agoThe committee loves overloading. IMO they overuse it. I think once you start thinking "this overload only participates in resolution if..." you should start considering different functions.
- staticassertion 5y agoI feel like there was success with overloading `<<`, which is weird but very appealing for students IME, and suddenly overloading everything was on the table.
- tialaramex 5y agoOverloading << is part of Stroustrup's iostreams toy and thus enjoyed the advantage that the language's creator was advocating it from the outset (it pre-dates the C++ standard library). I doubt that anything so ugly and dangerous would be standardised even in C++ today. Because this is actually still a shift operator, it retains all the precedence of the shift operator even when tired humans think of it as as a clever new stream out operator. So if you're in a situation where shift has precedence, the operator fires, and too bad if that wasn't what you'd intended nor what makes sense to a human reading the code. Oops. Some languages let you mint new operators (from some limited combinations of symbols) or allow infix function calls, or by some other means provide for you to nicely extend syntax here, but the overload of unrelated operators was IMNSHO an ongoing disaster whose popularity with programmers is unexplained, like C's decision to treat an array as just the pointer to the front of the array. But I'm a cranky old man, I also don't like the fact that Rust's + concatenates Strings (this isn't inherent in the language since String isn't a built-in type, in Linux kernel Rust nothing like this exists, because Linus would throw a fit, but in the out-of-box runtime environment Strings implement the Add operator as a concatenate operation).
- uvdn7 5y agoAnd starting writing the standard instead of describing high level expectations but describing the implementation (code).
- blindseer 5y agoUgh. I'm firmly of the opinion that if anyone uses a sane programming language first, they'll absolutely do anything they can to avoid C++. Corollary being, 1) if C++ is your first language, you'll end up learning all these rules and exceptions to the rules and assume that is just how it is (this is the way I think about Python), and 2) if you use C++ you are aiming for performance that alternative languages cannot provide. I'm glad the gap between alternatives and C++ is narrowing. If I could, I would never write another line of C++ again. Rust and Zig are FAAAARRRR better alternatives to me personally, purely because there's fewer gotchas I have to keep in my head when attempting to do anything with those languages.
- rixed 5y agoIn my case I'm writing C++ because I want to use a library implemented in C++. One of the gripe I have with C++ is that it has replaced C as the goto language for general purpose libraries, yet it's hard to built bindings for another language (whereas bindings to C are trivial).
- seanstrom 5y agoI’m in the same boat, I’m learning game engines and so many libraries are in C++. It feels impossible to use Rust or Zig, but I have hope I can use Nim. It can compile to C++ and has a simple-ish way of wrapping C++ code. Maybe it would interesting for you too?
- pjmlp 5y agoCorollary 3) the platform only offers C++ on the toolbox alongside the managed languages on the SDK and adding another language will create more complex toolchain, complicate the build server, have an impoverished IDE experience and rely on third party libraries of various levels of quality for FFI bindings.
- jcelerier 5y agoI'm curious about your use case for calling the vector(size_t, value_type) constructor (vector<string> v1 { 42, "foo" }). I'm on a codebase of a few hundred kloc and the need for a vector initialized to anything but the default value pretty much never came up. It uses boost, Qt, llvm and two dozen other libraries, yet there is a grand total of eight instantiations of that constructor in it. When putting a breakpoint, it turns out that all the calls to it I could trigger actually just initialize with the default value statically (e.g. vector<T*> v{x, nullptr};).
- rixed 5y agoEasy because since the bite I'm adding some comments after those initialisations where I really intend to call a given constructor. Three instances I could grep immediately, all from the same file: std::vector<std::tuple<std::optional<qreal>, QString, QColor>> values( // Not list-init numValues, std::make_tuple(std::nullopt, QString(), QColor())); (...) std::vector<size_t> nextTupleIdx(numValues, 0); // Not list-init here! std::vector<bool> done(numValues, false); // Not list-init here! I do not doubt a single second that there are 36 ways to write this that are simpler, more efficient and more readable. Yet I would like to hear your suggestion.
- jcelerier 5y agoAll your examples can be replaced by std::vector<T> vec(numValues); as vector value-initializes. Personally I prefer an explicit reserve or resize, but still..
- LAC-Tech 5y agoCan someone explains why it prints that?
- CJefferson 5y agoThere are two different features interfering, which were added at the same time. The {42,1} is an "initializer list", which was a way of passing a list of things to a constructor. However, at the same time, something called "uniformed initalization" was added, which used {}, to "clean up" how constructors work. However, from looking at a piece of code it's impossible to know if it is trying to call "initializer list" or "uniformed inialization". The "initalizer list" wins in this case, when the items are all things you can put in the vector.
- pierrebai 5y agoOh how I agree about the uniform initialization! And to make matter worse, I now work on a code base where it is the mandated form in the coding standard. At least your initial example now gives me ammunition against it, but too late for this coding standard. It makes code look silly, too, as now initialization looks different from assignment. int i { a + 2 }; i = a + 4; int j = a + 2; j = a + 4; // ah! consistency!
- ncmncm 5y agoIt is good for initialization to look different. It is different. Not so much so for int, but maybe hugely different for other types.
- pjmlp 5y agoTo build up on sibling's answer that isn't the same thing. The first one will call the initialization constructor, whereas the second form will initialize the object and then apply one form of copy construction, depending on which ones are available (user provided or compiler generated). It just happens that for int that doesn't matter in practice.
- tialaramex 5y ago
- CJefferson 5y agoThis was, in my opinion the single worst thing added to C++ -- it's what made me quit the C++ standard's committee, as it was clear (to me) how much of a mess things were. Different people wanted "{ } for unified construction" and "{ } for initalizer lists", and we ended up with this mess which made 0 people happy, and ruined unified construction.
- boppo1 5y agoI'm at the beginning of a programming career, about to lean real heavily into learning C++ because it's standard/necessary in the field I want to join. Stuff like this terrifies me that I'm signing up for some kafka-esque frustration.
- CJefferson 5y agoThe way I would think about it is: C++ isn't any weirder than English. As long as you are happy to accept there are things just there for weird history reasons, it's not too bad.
- boppo1 5y agoThanks, this is heartening. People new to english still manage to get their point across even if it sounds funny.
- beached_whale 5y agoGenerally in C++ one should use Type name = Type( args... ) style to be the least surprising. Prior to C++20 that would be aggregates. It's really too bad that initializer_list gets special treatment, and it's universally wart in C++. The alternative would have been vector{ { 1,2,3} } and that would have been fine.
- uvdn7 5y agoC++‘s initialization is utterly broken. Eg to understand the difference between just ‘struct Foo f;’ and ‘struct Foo f{};’, you have to come across about 10 different kinds of c++ initialization terms. Is there a way out of this (serious question)?
- makecheck 5y agoWorse, even without the vectors, the initialization of single variables of these types would be different with the same syntax, e.g. string s; // initialized (empty) int i; // NOT initialized (garbage value) static int i; // initialized (to zero) char c; // NOT initialized (garbage value) ...I mean, it’s always been a complete mess.
- kazinator 5y agoWhen I was programming C++ regularly, which was C++03, I wrote a robust format string system which could catch all mismatches against the format string at run-time. Which is good enough in practice if you actually test the code paths. What's valuable is being able to compile format strings into faster code, like the formatter macro in Common Lisp.
- superkuh 5y agoC++?? every 3 years isn't nearly as bad as say, the Rust situation, but it does mean that a linux desktop distro compiler can only compile stuff from "hip" devs writing in C++ for about 3 years after the distro release. It means if you chose to use these language features the vast majority of people will not actually be able to compile it. So balance that. If you're not just distributing binaries, if you have geek end users compiling, maybe don't always use the latest bleeding edge C++?? features.
- jcelerier 5y agoNah, this is also why the Linux desktop is behind. On Windows I build on win10 VMs with the very latest C++20 features and can ship back to Win7 because Windows does not idiotically tie a compiler version to an operating system.
- superkuh 5y agoIf you have to use a VM to compile instead of doing it on your OS you've lost the game too. It is a cross-OS problem with almost all modern software.
- pjmlp 5y agoI am quite curious when clang will catch up with C++20 (GCC is much better). Meanwhile I am enjoying modules in VS 2022, even if there are some hiccups.
- pjmlp 5y agoC++ is one of my favourite languages, however there is a big difference bettwen being able to write modern C++ in side projects, and what most companies consider C++. Enjoy a sample of AOSP source code, https://android.googlesource.com/platform/art/+/refs/heads/master https://android.googlesource.com/platform/art/+/refs/heads/m...
- deleted 5y ago[deleted]
- throwawaybbqed 5y agoWow ... I want to pull my eyes out now. Is this really some uber critical path in the code or did the author(s) have too much time on their hands/optimizing some other metric (e.g. promotion, proving how smart they are, attempting to get job security). I am also astounded by two things related to documentation .. it is nearly non-existent, and where it exists, seems to provide almost no context to someone other than the original authors. You posted this for a reason .. would be good to get your thoughts. edit: adding one more point. I went to a fairly high-ranked university(top-20). We would get graded based on how clear our code was, comments (both for functions and inline comments). This code would get a zero on those metrics.
- emteycz 5y agoHmm... I can't see how the code is unreasonable, given the complexity of the task at hand. Could you tell me what could be improved about this code (code itself, not docs etc)?
- jcelerier 5y agojust opened a file and...ugh https://android.googlesource.com/platform/art/+/refs/heads/master/dalvikvm/dalvikvm.cc#132 https://android.googlesource.com/platform/art/+/refs/heads/m... like, just this, basically C: if (strncmp(argv[arg_idx], "-XXlib:", strlen("-XXlib:")) == 0) { ... is just so complicated and error-prone over if(std::string_view{argv[arg_idx]}.starts_with("-XXlib:")) ... (which I guess is the intent)
- jjice 5y agoI don't write C++ for work and I've written very little ever, but it seems like C++ and PHP (which I do write daily) have a similar trend. They get shit for being old and bad, but people haven't seen the myriad of new features, safety, and solid ecosystem.
- pjmlp 5y agoThat is true, I have plenty of stuff to complain about C++ and PHP, but also have similar list about Python, Java, C#, F#, C and many other languages of similar age.
- still_grokking 5y agoIt's impossible to retrofit sanity ex post facto into something that's broken by design. The nonsense on the base layers will always creep into the higher levels through unavoidable abstraction leaks (which are usually unavoidable exactly because said nonsense on the base layers exists in the first place). That's why repairing design mistakes is only achievable by rewrites, inevitably breaking compatibility with the old system in this process.