Sadly 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).
I 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.
The issue is that it took 7 years for consteval to be added. Constexpr is extremely prone to "Silent" bugs, where you may mistype it or do something not allowed in a constexpr, the compiler builds it, and it's never actually compile time. It doesn't tell you, it doesn't warn you, it's just never going to be compile time since it's not valid. consteval fixes this by being "Must be compiletime". In my view, it's as if we only had template arguments and now they finally added actual arguments.
It should be explicit on what the program is going to put out, especially in a language like C/C++. When you're writing code close to the metal, you need to make sure it's exactly what you wrote. It may be a target platform difference, since I don't use the STL and mainly using C++ language features to target extremely low level devices or goals. In an application dev environment, I can see how constexpr "doing it for you" is fine, but the fact they only had one and not the other is a travesty and has so many footguns.
For example, I wrote a DRM program that required an additional buildstep to yell at the developer if they exposed strings or confidential information in the binary. This is solved by consteval, which should've been in there since the beggining.
You could always know if a function was compile-time or not based on the usages. Eg, static_assert the output or put it in a constexpr value, and it's guaranteed to be compile-time evaluated or it didn't compile.
consteval is helpful in iterations during development to catch that, and I like it as such, but it's definitely not a constexpr replacement nor what constexpr should have been. It's a very small subset of constexpr usages.
Not in C++ it isn't. If you want to change the spec to allow that go for it. But skimming eg. Zig where that's the case, it's also quite non-obvious from the docs if you can know if a function can be used in a comptime statement or not.
`constexpr` makes "you can use this at compile time" an explicitly documented attribute of the function, instead of just a guess or by needing to read the implementation.
This is more of a marketing or teaching problem than an actual language design problem. It's not about the compiler overriding the programmer, it's just designed for a different purpose.
There were already a bunch of places in the language that required compile-time evaluation- array sizes, template args, static_assert, case expressions, etc. "Can be" is all about enabling existing APIs to be used in those contexts. You can't (and don't want to) force those APIs to run exclusively at compile time, because programs are already using them at runtime all over the place!
This talk about compile time evaluation got some people thinking about all the other things they'd like to do at compile time. And there is a way to do that with just `constexpr`- `constexpr` variable initializers are a new "compile-time-only" context just like array sizes/etc, so you can decide at the leaves what to compute ahead of time, without forcing the callees to be exclusively compile time.
But there seems to be some kind of disconnect in how people learn about constexpr, where they hear "compile time" and imagine a different design than what actually went into the language, then get even more confused when they hear "can be" and imagine it as something that happens at the compiler's whim rather than deterministically based on the calling context.
no, constexpr was correct for a reason. it's great to have a single function that can both be runtime or compile-time if allowed. it results in less code. they knew what they were doing.
I 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.
Yeah 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`
You can't demand too much too fast from compiler developers or you end up with Itanium. C++20 still isn't widely available. MSVC doesn't even support all of C11.
Did you mean C11 there or C++11? I'm not sure why C11 is relevant in a discussion about C++. MSVC's support of C has been abysmal for ages, but this has no reflection on its C++ support. Of which it definitely supports all of C++11. And 14. And 17. And even complete support for C++20
For C++20, GCC is "only" missing module support, but otherwise supports everything else. Clang is lagging behind, though.
I mean C11 because it's an example of a major release in a major language that became unusable in practice because a compiler vendor decided it wasn't important to support it in full. Now you can't bump your compiler version to C11 if you want stable portability. This is relevant because it's what happens to C++ if it demands too much from compiler developers.
>For C++20, GCC is "only" missing module support, but otherwise supports everything else. Clang is lagging behind, though.
Then I'll rephrase: it's not only not available widely, it's not available at all.
C isn't a major language on windows, at least according to Microsoft, whereas c++ is. It'd be like complaining about the state of Java on iOS. C11 doesn't demand much of anything from the compiler. It's definitely not from overbearing demands made by the language.