16 ms·
Const vs. constexpr vs. consteval vs. constinit in C++20
- slashdev 4y agoC++ is a great real world example of ignoring the advice "if you find yourself in a hole, stop digging". They have this problem with complexity and the only strategy they have to tackle it is by adding more complexity. Maybe they're going to overflow back to 0. Or they'll come out in China. Who knows. I've moved on.
- klyrs 4y agoI've got my eye on Cpp2... Herb says he isn't interested in making it an official language but I suspect that once it stabilizes it will be an attractive migration.
- elteto 4y agoBut then you have Google with Carbon… which is a direct competitor to cpp2. Apple hasn’t shown interest in either, and MS will of course most likely support cpp2. Without the giants aligning their interests I’m afraid there will be a split in the community. Clang’s std C++ library is already behind GCC’s because Apple and Google have “moved” on.
- bsldld 4y ago> ...Apple and Google have “moved” on. Apple moved to Swift, but what has Google moved to?
- elteto 4y agoIt’s in the process of “moving” on to Carbon.
- devnullbrain 4y agoThat is a lot of optimism for a 2022 project from 2022 Google.
- elteto 4y agoEverything starts somewhere. I believe Chandler Carruth is leading the project so that means non-trivial resources are being dedicated to it. Their timeline is also fairly aggressive.
- ameliaquining 4y agoThey're also simultaneously looking at Rust as a possible successor to C++ (e.g., by developing better interop tooling). It's believed that at most one of these projects can succeed in the long term.
- elteto 4y agoInteresting, thanks for the insider take. I honestly would love if they went with Rust.
- tialaramex 4y agoHerb doesn't even want to default to immutable local variables (what he as a C++ person calls "const by default"). Obviously Cpp2 isn't finished enough for this to necessarily jump out, but Herb figures if we make a variable then we must intend to vary it, which is one of those claims I expect from newbie C++ programmers keen to defend their new language. No, come on Herb, Kate Gregory has told us why there are variables, they are names for things. The machine doesn't need names, but the human maintenance programmers do. As a Microsoft employee I'm going to hazard a guess that Herb spends a lot less time staring at C++ real humans wrote before they died/ retired/ got fired without notice than Kate does in her consulting job. She knows what she's talking about.
- ameliaquining 4y agoI'm honestly not convinced that immutability for local variables is a particularly useful feature. Within the scope of a single function, it's usually pretty easy to see if a variable is being reassigned or not; there aren't the same kind of programming-in-the-large preventing-spooky-action-at-a-distance benefits that come from immutability across API boundaries. You increase the language's complexity and learning curve, for a benefit that's rather speculative and unclear. (The exception is closures; prohibiting a variable from being reassigned after it's been closed over is useful because anyone reading the code may expect one of two conflicting behaviors depending on context, and so it's good to instead write the code in a way that doesn't have that ambiguity. Java got this one right.) A post articulating this point, by the person primarily responsible for Rust's shared-xor-mutable architecture (so presumably he has some idea what he's talking about, though note that his argument did not carry the day): https://smallcultfollowing.com/babysteps/blog/2014/05/13/focusing-on-ownership/ https://smallcultfollowing.com/babysteps/blog/2014/05/13/foc...
- tialaramex 4y agoNotice that what you're asking for is to abolish const local variables. Which also isn't what Herb offers, this was the status quo in C during the K&R era because "const" didn't exist in K&R C. If you actually want const local variables, just not by default, you're not actually agreeing with Niko.
- cpeterso 4y agoFor people curious about Herb's Cpp2, here's a presentation he gave at CppCon 2022: "Can C++ be 10x Simpler & Safer? (Simplifying C++ #9 of N)" https://www.youtube.com/watch?v=ELeZAKCN4tY https://www.youtube.com/watch?v=ELeZAKCN4tY
- hinkley 4y agoC++ is a bit of a honey trap for people who love complexity. Unfortunately it's only caught a small fraction of all of the people who worship at that altar.
- FpUser 4y agoI love simplicity. I also love performance. This is why I use modern C++ for backend servers. It allows me to write very simple code that is still very performant (actually leaves standard stacks in the dust). I sure do not fall into honeytraps so for me complex languages like C++ is an advantage as I can always find what works the best for particular task.
- namkt 4y agoDo you use any public libraries for those backend servers, or is it all home-grown? Curious what's at play.
- FpUser 4y agoyes I do: spp-httplib, taopq, spdlog, rapidjson. Also some other extras and alternatives depending on particular needs but the ones mentioned are enough to get one started on generic web app backend. What I do not and likely will not use are big opinionated frameworks. Yes I do write my own libs as well but those are very domain oriented and mostly serve needs of particular application. Nothing exciting there.
- fredrikholm 4y agoDo you have any open sourced projects wit this setup? I have a soft spot for (C) single header libraries, would be interesting to compare.
- kaba0 4y ago> I have a soft spot for (C) single header libraries May I ask you why? The whole preprocessor macro thing is just a disgusting hack that compiles slowly, is error prone and is not even expressive enough for the most basic of things.
- gavinray 4y agoI don't write C++ for a living, and only have ~2 years' experience writing it for some hobby projects on weekends. I've found that the way I'm most productive is by using data-oriented design where I put everything in structs and don't use classes. I still use a lot of modern C++ library features, but it reads more like C. For example: struct BufferPool { alignas(PAGE_SIZE) char frames[BUF_POOL_NUM_FRAMES][PAGE_SIZE]; std::atomic_uint32_t free_frames[BUF_POOL_NUM_FRAMES]; std::atomic_uint32_t pin_count[BUF_POOL_NUM_FRAMES]; std::atomic_bool is_dirty[BUF_POOL_NUM_FRAMES]; std::atomic_uint32_t page_id_to_frame_idx[]; }; std::span<const char> BufferPool_get_record(BufferPool* pool, RecordID rid, int db_file_fd); What's nice about having all this stuff thrown into the language is that you're free to pick and choose what you want to adopt from it. For a long time, I tried to cram everything I wrote in C++ into an OOP pattern with classes, and it just didn't jive with me. Then I stopped doing that and started writing it more like TypeScript/Kotlin/C which I'm more familiar with and it's been a lot more pleasant ever since. There's been so much great stuff in C++ 17/20/23 and you can just cherry pick all the bits you want to use out of it and ignore the rest.
- dagmx 4y agoFWIW, structs and classes are largely identical in C++ , with the exception of public/private defaults. So using one over the other doesn’t really change anything with regards to data oriented design.
- gavinray 4y agoAye, as opposed to D where structs are value types and classes are reference types It's just a small annoyance to have to put "public:" at the top of every data-class definition So I use structs everywhere but you're completely right, no real difference
- dagmx 4y agoYeah I do the same as you since I write a ton of Swift (which does the same delineation as D). It’s mostly just a mental marker for myself that I want to treat one as a value type.
- joebaf 4y agoon the other hand with more options you can express more and write safer code (for example with constinit which solves static order init fiasco...) And if you don't have enough knowledge you can just stick to const. What re alternatives for a system programming language? (Rust seems to be fine, but still it's not super easy...)
- fluoridation 4y agoI don't agree with that analogy. For example, templates were for sure complex, and they're very much a complete feature. That is, they haven't been made more complex over time. If we accept that the committee has already dug themselves into a hole, what they're doing is digging themselves out by digging out the entire field to the same depth, thus eliminating the hole originally dug, which I think it's a perfectly reasonable strategy.
- kllrnohj 4y ago> For example, templates were for sure complex, and they're very much a complete feature. That is, they haven't been made more complex over time. I agree with your broader point but parameter packs (aka, variadic templates) were an addition to templates made in C++11. So strictly speaking they have gotten more complex.
- fluoridation 4y agoFair enough, but that addition wasn't to solve the problem of templates being too complex, but to support usages that were previously impossible.
- usrnm 4y agoThey were possible and widely used, but a lot less ergonomic. You "just" had to copy-paste some number of instantiatons for the number of arguments between 0 and, say, 50.
- fluoridation 4y agoWasn't it also at the cost of compilation memory? I still remember the time when it was easy to crash compilers by just giving them hard enough templates.
- cbsmith 4y agoI mean, that's just the tip of the iceberg. Templates have evolved a great deal over time, and continue to do so (C++20 added Concepts).
- g42gregory 4y agoI feel that this is a feature, not a bug. While I don't use C++ extensively, I think the Industry needs at least one language, which does not constrain the developer in any way. I think such a language is currently C++. It has all kinds of guidelines now to stay in the "safe zone", but there are many developers who (1) need unfettered access to the hardware and/or (2) need all kinds of language capabilities to write an extreme performance code.
- virtualritz 4y agoCould you elaborate what I can do in C++ that I can't do in Rust (using unsafe, if I must)? For context: I've been writing code in C++ for most of my career (25+ years) and being for VFX/3D rendering it was mostly performance critical code. Now I write Rust for some very performance critical tasks in finance ...
- eloff 4y agoI also use Rust now. If you use unsafe, there is little you can do in C++ that you can't do in Rust. However, some things like data races and mutable aliasing are permitted in C++, but not in unsafe Rust, as they invoke undefined behavior. The Rust nomicon has more details about what's allowed.
- virtualritz 4y ago> However, some things like data races and mutable aliasing are permitted in C++, but not in unsafe Rust, as they invoke undefined behavior. Define 'permitteed'. Unsafe is, among other things, exactly that. It tells rustc to permit you to do things that are ... well, unsafe. Including the ones you listed. Maybe you don't understand the meaning of unsafe in Rust? Unsafe causing UB is a possibility. As is taking two &mut refs to the same memory location using exactly that keyword. And that example works for multi-threaded Rust code using a shared resource accessed as such too.
- kaba0 4y ago
- Animats 4y agoI'm glad I switched to Rust. In C/C++, the language designers can't take anything out. That would break things. There's so much legacy code. C hasn't even totally removed "strcat", etc. yet. That should have been removed in the previous century.
- devnullbrain 4y agoThis is a surface-level meme that just doesn't reflect reality. In old C++ you had to spend all your time worrying about manual ctors and memory management. These problems have been erased by improvements to the language. You don't even use raw pointers any more. The language is less complex to use now than it was 10 years ago. If you've moved on then your insight is outdated.
- pjmlp 4y agoKind of true, if we ignore all the code that is in production and no one is going to rewrite for C++20 ways of coding.
- devnullbrain 4y agoWhich would not have its problems solved by halting C++ development or moving to a new language
- pjmlp 4y agoAnyone working on those codebases needs to be aware of the new ways, while mastering the old ways. The ideal modern C++ without having to worry about "deprecated" ways of coding, is more the exception than the rule.
- usrnm 4y ago> In old C++ you had to spend all your time worrying about manual ctors That doesn't even make sense. Maybe you meant "destructors" but even then it has nothing to do with reality
- devnullbrain 4y agoI mean constructors. It's the exception to have to do anything meaningful in the body of a constructor in modern C++ - you can do a lot with member initialisation lists, delegated constructors and defaulted/deleted constructors (remember boost::noncopyable?). And your assignment operators will actually be exception safe.
- userbinator 4y agoThe trick with C++ is to use and pick things to work on that haven't devolved into a massive abomination of complexity just to be trendy and "modern". I've found that something like the classic (pun intended) "C with classes" style is a good balance. Personally, I prefer to use C (C89) which is high-level enough to be reasonably productive, while at the same time not high-level enough to discourage the creation of overly complex code. There are surprisingly frequent posts here from people who have written their own C compiler. I don't think I've seen a single C++ one yet.
- estebank 4y agoAre you baiting Walter for a reply? :)
- JonChesterfield 4y ago`clang++ -ffreestanding` (without a standard library) is growing on me as a C89 replacement. There's some annoyances like std::launder that you need to implement using compiler intrinsics but it's feasible.
- overgard 4y agoEh, it's gotten more complex sure, but in real world code most of this solves real problems, and even if it's technically adding to the language in practice most of the new stuff replaces old patterns. I don't think anyone that's used c++20 would want to go back to c++98, or c++11.
- jokabrink 4y agoWhenever I see that C++ added some language extension, I can't help but think about Bjarne Stroustrup's "Remember the Vasa" Paper [1] and wonder if he had meant this type of complexity he warned against... - [1](https://www.stroustrup.com/P0977-remember-the-vasa.pdf https://www.stroustrup.com/P0977-remember-the-vasa.pdf)
- tialaramex 4y ago"Remember the Vasa" is why you can't have your feature, it doesn't apply to Bjarne.
- orange_joe 4y agoI hate C++. I work with it professionally and have for years. The entire language feels like an anti pattern at this point. I’m repeatedly told how incredibly powerful this language is if I only use this preferred set of language sub features. But this whole approach violates the entire premise of a type based language, which is to offload as much complexity as possible onto a compiler so that you can get compile time warnings & errors. What’s the point of a compiled language if half the language constitutes a foot gun.
- cartoonfoxes 4y agoSame here. I keep eyeing Ada and waiting for the compiler prices to drop.
- micronian2 4y agoAre you unaware of the FSF version of GNAT that is part of GCC that is free to use, even for developing proprietary software?
- cartoonfoxes 4y agoI'm aware of it, and I'm not aware of anyone using it for proprietary software in the kinds of projects where Ada would come up in discussion. FSF GNAT + Alire are fine as a hobbyist toy and for open source, but they're not in contention for [workjob]. FSF GNAT isn't just unsupported, but also very thinly documented. And that's if you're only targeting Linux or Windows on x86, and not embedded devices with a cross-compiler you need to build yourself. The basic Windows / Linux versions of the cheapest commercial Ada package only recently dropped to high 4-figures / seat. The equivalent cross-compilers are still $$,$$$.
- devnullbrain 4y agoI don't understand how this comment applies to this link. These features are designed around moving as much computation and verification as possible to compile time without using templates. If you need to.
- gpderetta 4y agoIt is possible that constexpr keyword for functions will soon go the way of the dodo^Wregister keyword. It is was a pointless keyword added to just to get comp-time evaluation proposal get through the approval process and the the authors have already apologized for it multiple times. GCC has already added -fconstexpr to implicitly mark all functions as constexpr.
- nynx 4y agoThis seems like it could cause issues. Being able to evaluate at compile time is part of the api surface of a function. If it’s not explicit, it could be very easy to accidentally change the internals of a library to not support consteval, but without changing the explicit signature.
- gpderetta 4y agoThe problem is that constexpr already is not sufficient to guarantee that.
- cbsmith 4y agoHow so? constexpr doesn't guarantee that an expression is evaluated at compile time, but it does guarantee that it could be.
- jcelerier 4y ago> but it does guarantee that it could be. in which sense do you mean this? consider for instance constexpr int foo(int x) { if(x < 0) throw "error"; return x; } I would say that "guarantee that it could be" means that as long as the function definition itself "builds" / is validated by the compiler, you can use it in a constexpr context yet this is not the case here: constexpr int a = foo(123); // works fine constexpr int b = foo(-123); // compile error int c = foo(-123); // works fine so having "constexpr" in the API does not mean that your code will always build ; as soon as you have constexpr the entire implementation of the function is part of the API, thus making the keyword moot like gpderetta says
- daniel-thompson 4y agoI'm not a language designer and don't want to be one - I'm open to the idea that these new keywords are actually the simplest, most composable way to address these use cases - but good grief! The burden of complexity weighs so heavily on this language that understanding how/when to use its features to solve your problem can easily be as or more difficult than the problem itself.
- maldev 4y agoSadly with all of these, it was needed. Constexpr was an monstrosity. Whoever on the comittee board made it "CAN BE" has caused untold horrors on some projects i've worked on. consteval is nice, it's just constexpr, but forced on the compiler, which is how it should've been. There should never be "CAN BE", it's my least favorite thing about C/C++. The compiler shouldn't override me, and consteval is a step in the right direction and has made me target all my projects to c++20(Which is luckily easy since I don't use STL functions).
- cbsmith 4y agoI can't see how constexpr could be used for what constinit does. Indeed, there's a part of me that thinks constinit is kind of a poorly chosen name/keyword.
- kllrnohj 4y agoYeah constinit seems poorly named. Yes it's "constantly initialized", but the result isn't actually "const", it's still mutable! Which is a great property to have as an option (and indeed a big differentiater vs. constexpr), but it seems like `staticinit` or something would have been more clear that it's very unrelated to `const`
- kllrnohj 4y agoI disagree that consteval is what constexpr should have been. It's great to have a function that can work both at compile time and at runtime. `std::max` being a simple & obvious such example. You of course need that at runtime, that's the classic verison. But why shouldn't it be able to happen at compile time? That's a silly restriction. And thus 'constexpr' - it can run in both modes, depending on when & where it's called. 'consteval' then is for when it must happen at compile time, which is a rather narrow (but very useful!) subset of constexpr. Now, what is silly is that `if constexpr` is only allowed to happen at compile time. That should have been `if consteval` instead, the ordering of these additions is unfortunately reversed.
- maldev 4y ago
- ergonaught 4y agoThis is the sort of thing that pushed me away from C++ a couple of decades ago. I remain perplexed that the "solutions" to C++'s "problems" have largely been to continue overcomplicating the language.
- jeffbee 4y agoLiterally nothing in the article, except `const`, existed "a couple decades ago".
- ergonaught 4y ago“The sort of thing”.
- devnullbrain 4y agoSmart pointers overcomplicated more than auto_ptr? Default ctors are an overcomplication? Optionals worse than void pointers, variants worse than unions?
- catlifeonmars 4y agoWell now you have both. So yes, strictly worse from a language complexity perspective because now there are two options to choose from, and a significant, nonzero fraction of developers are going to choose the “wrong” option, and leave me to fix their bugs. Hell I even choose the wrong option half the time.
- DonBarredora 4y ago
- wvenable 4y agoA lot of negative comments here but these keywords seem perfectly reasonable to me. If I actually have a place where I'd need them, I'd be able to understand which one to use and why. I like to be able to do more compile-time evaluation and it's definitely a lot less confusing now than abusing templates for that.
- kllrnohj 4y agoYeah I find these keywords perfectly approachable & straightfoward. I find them easier to understand and rationalize than, say, Kotlin's set of with/let/apply/also/run ( https://kotlinlang.org/docs/scope-functions.html#function-selection https://kotlinlang.org/docs/scope-functions.html#function-se... ) The comments all seem like just mindless anti-C++ circle jerking, with zero relevance to what's actually being discussed in the article. But that's sadly quite common with C++ articles here. If the title has C++, expect to see the same rants regardless of the article.
- throwawaymaths 4y agoOk but it's 2022 and something like ziglang can do all of these things with two keywords (const and comptime). Why does C++ need four?
- jeffbee 4y agoBecause of path dependency and backwards compatibility. C++ has 30 years of legacy code to build. Zig doesn't even exist yet; after 6 years it is still in "preview".
- kllrnohj 4y agoIt looks like in zig all functions are `constexpr` ? As for `constinit`, it looks like ziglang doesn't have an answer for the problem that constinit solves. That is, ziglang appears to have the same bugs here that C++ did before constinit was added.
- anonymoushn 4y agoCan you give an example of a bug in a Zig program caused by the lack of constinit? It seems like Zig just does not have the delayed initialization of static and thread-local variables that C++ has, but I'm not completely sure of this.
- 323 4y agoLess known fact is that it's called C++23 because there are 23 ways to initialize a variable. Of course, it's a joke. In reality C++23 has only 20 ways to initialize a variable: https://www.cppstories.com/2022/init-string-options/ https://www.cppstories.com/2022/init-string-options/ https://blog.tartanllama.xyz/initialization-is-bonkers/ https://blog.tartanllama.xyz/initialization-is-bonkers/
- brianjacobs 4y agoIn summary: constexpr variables are constant and usable in constant expressions constinit variables are not constant and cannot be used in constant expressions constexpr can be applied on local automatic variables; this is not possible with constinit, which can only work on static or thread_local objects you can have a constexpr function, but it’s not possible to have a constinit function declaration
- chris_wot 4y agoconstinit allows for constant initialization. Why, how enlightening! Now... what is constant initialization?
- fractalb 4y agoI didn't understand the difference between constinit and consteval. It appears that constinit is just consteval applied to global/static variables. Why two keywords then?
- gpderetta 4y agoThey are unrelated. consteval is applied to functions and asserts that a function definition can be evaluated at compile time, and only at compile time, for all possible arguments; the compiler is required to check this. This is different form contexpr that merely allows it and possibly only for a subset of the arguments. constinit is applied to static variables and asserts that the initialization is static (static variables can otherwise still be initialized dynamically on startup or on first use).
- fractalb 4y agoBoth consteval and constinit are evaluated at compile-time, right? If yes, then why two different keywords?
- jgaa 4y agoC++ is starting to show that it's Designed By Committee ;) I'm a big fan of C++. It's been my primary programming language since 1996. C++11 was awesome! I'm in the minority of the C++ developers that occasionally take the language (and the compilers - just like Internet Explorer was a great pain for "front end" developers for a decade, MSVC was a pain in the a* for C++ developers) for a ride to it's limits. However, the complexity of the language in C++ 23 is mind mind-boggling. The complexity in C++ 11 was quite frankly already overwhelming. I've worked as a senior and principle C++ developer in small startups and big established software companies. In the last decade, I've only met a handful of really qualified C++ developers (people who actually know the language, and how to use it effectively). Most of the "Senior C++" developers I've worked with can use basic things in the same way that average Java developers can use Java - but they know nothing about for example template meta-programming or how to do concurrency correctly. Many of them were just C programmers who at some point were thrown into a "C++ project" and learned how to "use classes", but still use C functions for starting new threads. In other words, In 2022 they have not even updated themselves to C++ 11. It's hard to learn C++ to an advanced level. It's /really/ hard. Most people don't have the personal drive to do it. At least not the majority of the C++ developers I've worked with over the years. They learn the basics, and then just use the knowledge they already have to do their job. Even I, and friends of mine that are even more enthusiastic about C++ than I am, are starting to feel exhausted by the ever increasing complexity of the language (and the libraries). One of them suggested to me to take a look at Rust. It's a lot simpler to learn Java/Kotlin (applications) or Rust (system programming) than it is even to maintain a good knowledge about C++. I still think C++ is a lot of fun, and programming exiting things in the language gets me into flow in a way few other activities can. It's also rewarding - I can do incredibly cool things, and I can incrementally improve on the way I solve the same problem each time I run into it in a new project. But that's me. Most of the C++ code I've seen in small and large companies stinks. The developers have the tool to do wonderful things - but like the Wizard's Apprentice - they don't know the tool very well, and they don't know how to use it. I think most of the projects started today in C++ would be better off written in a simpler language that the developers actually comprehend.
- xony 4y ago