5 ms·
> It's funny that of all the gazillion features C++ has supported a for well over a decade the C folks have been missing out on, they pick exactly the one super
by nuerow 5y ago
> It's funny that of all the gazillion features C++ has supported a for well over a decade the C folks have been missing out on, they pick exactly the one superfluous keyword in C++ to cherrypick onto C.
It looks to me that it's a significant improvement that's also a very low hanging fruit, given that C/C++ compilers that already support C++'s constexpr can trivially support it for C as well.
- saagarjha 5y agoNot every C compiler is a C++ compiler.
- NavinF 5y agoBesides that, I suspect nobody in this thread has looked at what compilers output. Compare the following programs that multiply 2*2: https://godbolt.org/z/avsac77aa https://godbolt.org/z/avsac77aa https://godbolt.org/z/Mznhrf1sq https://godbolt.org/z/Mznhrf1sq The only difference between them is that `len` and `result` are declared constexpr in the first program. Notice how without constexpr, both clang and gcc generate a slow call to mul() inside main() instead of just calculating 2*2 at compile time. I'm sure you could use LLVM opt to force to compiler to try harder than -O3 (and maybe that should be the default), but that will also make compile time longer. Real code is way harder to optimize than my 18 lines that are all in 1 file.
- deleted 5y ago[deleted]
- dataflow 5y ago> I'm sure you could use LLVM opt to force to compiler to try harder than -O3 (and maybe that should be the default), but that will also make compile time longer. Real code is way harder to optimize than my 18 lines that are all in 1 file. Evaluating code at compile time is not harder or even as much work as than optimizing it. If you ever wrote an interpreter you know that it's much simpler than optimized codegen. You can evaluate unoptimized code at compile time perfectly fine, and deducing whether that is possible is extremely fast in comparison. Which is why in C++ you see people litter constexpr everywhere they can regardless of whether the code is -O0 or -O3.
- NavinF 5y agoHey, by all means fix clang and gcc so that my example no longer requires a runtime call to mul(). After all, evaluating code at compile time is easy right? If you succeed in solving this problem in general, feel free to propose a change to the language that allows the use of expressions such as `mul(arr, arr+len)` anywhere you'd normally be required to use a constant. (That's what constexpr already achieves today) Btw I mentioned that you can make the compiler try harder with LLVM opt because constant-folding is an optimization. I dunno why you bring up codegen.
- manwe150 5y agoSince the compiler must verify the expression is constexpr-valid, it could annotate that automatically instead. However, I believe that generally the standard requires that the keyword be explicit so that compilers agree on what are legal programs, and don’t just declare it to be implementation-defined for what is legal in const-initializer contexts. But in clang, you’d need an frontend-optimization framework to do that reliably (due to recursion), and it doesn’t have one. In llvm, the Attributer framework is still relatively new, but is progressing towards that.
- dataflow 5y ago> However, I believe that generally the standard requires that the keyword be explicit so that compilers agree on what are legal programs, and don’t just declare it to be implementation-defined for what is legal in const-initializer contexts. The standard could just declare that anything that could be constexpr-evaluable must be evaluated at compile time up to a depth of at least N, or something like that, after which it is permitted (but not obligated) to be evaluated at runtime. Just like with templates, except over there the implementation just errors out if the template gets too complicated or impossible to evaluate. The standard already has minimum criteria like these for a ton of other cases so this wouldn't be any different to justify a keyword for it.
- dataflow 5y ago> Hey, by all means fix clang and gcc so that my example no longer requires a runtime call to mul(). They can just pretend every inline function has constexpr in front of it, and fall back to compiling them if they fail to evaluate it as constexpr. The constexpr doesn't tell the compiler anything it didn't already know or have to verify anyway. And bear in mind much of the standard library already has constexpr in front of it (and that's a pretty strong signal that it should've been implicit IMO). I don't know Clang or GCC's codebases to know exactly what to modify off the top of my head, but I'm pretty sure adding an extra 'constexpr' internally in the front-end would be utterly trivial as far as compilers go. No need for any optimizations to get involved (and it's important to understand this).