5 ms·
Do you mean that C++ could have done without `constexpr` and could have used the existing `const`? Because that has been my feeling for a very long time. Why no
by AlexanderDhoore 5y ago
Do you mean that C++ could have done without `constexpr` and could have used the existing `const`? Because that has been my feeling for a very long time. Why not expand the meaning of const in certain contexts. Compilers know if something can be evaluated at compile-time. No need for me to tell them explicitly.
- zarzavat 5y agoIt's not the same. e.g. const int x = readInput(); cannot be constexpr. Consider constexpr as a compile time assertion that a given symbol is available at compile time. If you didn't have the constexpr keyword then you would have have to inspect the definition to determine that every subexpression is constexpr.
- AlexanderDhoore 5y ago"inspect the definition" Yes, that's what I meant with "the compiler can do it".
- zabzonk 5y agoNot given C and C++ separate file compilation.
- zarzavat 5y agoThat might be OK in an IDE driven language such as Java, but I doubt the neckbeards writing C in a plain text editor would go for that level of implicitness. In C++ it might be more acceptable since you practically need an IDE since C++11 to resolve all the auto type inference.
- foxfluff 5y agoC neckbeard here. I do fully hope and expect and assume the compiler to fold constants and figure out as much at compile time as it can. This is the kind of optimization that doesn't make the code harder to reason about, even when coding with ed, since the logic and ultimate result of these expressions does not change. Heavy type inference, overloading, and inheritance are a completely different beast and they make the code a lot more opaque.
- deleted 5y ago[deleted]
- nine_k 5y agoWhy not const int x = const foo(bar(y)); ?
- mpyne 5y agoThe compile can (and will) do that at run time, it just won't let the code alter x afterwards (either at compile time or run time)
- SuchAnonMuchWow 5y agoYou should check Zig comptime keyword, which does exactly that. Its the feature from zig I miss the most in C.
- User23 5y agoThat sounds like a subset of EVAL-WHEN[1]. [1] http://clhs.lisp.se/Body/s_eval_w.htm http://clhs.lisp.se/Body/s_eval_w.htm
- pjmlp 5y agoYes, all the constsomething is superfluous, as proven by Circle. https://www.circle-lang.org/ https://www.circle-lang.org/ Unfortunately, there is a big political war ongoing, so instead C++ keeps collecting const.... keywords.
- voldacar 5y ago"Constexpr" is possibly the most hideous keyword in any programming language. My eyes vomit a little each time I read it. They could have just used "pure" like in D, but this is C++, so that would be too sane and obvious.
- pjmlp 5y agoPolitics, check the outcome of the networking vote.
- hmfrh 5y agoIntroducing a new keyword means that all existing code that uses the new keyword as an identifier will break. That's why the `constexpr` keyword is deliberately weird. It's also why they reuse keywords like `using`.
- kevin_thibedeau 5y agoThey could just use the reserved keyword naming like the C committee does.
- nly 5y agoI can't confirm in this specific case but, more often than not, the reason for these redundancies is a fraction of the committee felt uncomfortable with the implicit solution, so the keyword got added.
- pjmlp 5y agoThere is a video about the story background, where a group of kids play the role of the committee voting down Circle.
- dataflow 5y agoBasically, yeah. You don't even need 'const' for this. Under the as-if rule, subsets of the program could always already be evaluated at compile time and have the result substituted in the program. Compilers already did that when they had the definition handy. Like just do int x = f(5); and then define int f(int x) { return x * 2; } and you'll get int x = 10; in any compiler without any keywords whatsoever. The constexpr keyword just cluttered the code for no good reason.
- NavinF 5y agoIn theory compilers can always optimize constant expressions, but they don't IRL. See my example above where I multiply the elements of an array containing {2,2}: https://news.ycombinator.com/item?id=28886999 https://news.ycombinator.com/item?id=28886999 My code is C style and unrealistically simple, yet the compiler can't even constant-fold that. If you've looked at the output of real compilers, you'd know that it's unrealistic for a language to let you to use the result of an arbitrary function call where you'd normally use a constant.
- dataflow 5y agoI'd already replied to you on that example and explained this has nothing to do with optimizations as far as performance and mechanics go. The only relevance of optimizations is to show that the language semantics always permitted it. Not to suggest an optimize needs to be run to actually do this.
- comex 5y agoIt depends. For one thing, constexpr guarantees that errors will produce compilation failures. (At least it guarantees that when used in certain ways; unfortunately C++ overcomplicates things.) In a version of C that doesn't have an explicit constexpr keyword but does allow the compiler to treat arbitrary variables as constants, you could perhaps approximate this by using a value in a context that forces it to be a constant expression… e.g. `const int x = foo(); _Static_assert(x == x);`. But that's a hack. Much better to have an explicit way to say "please evaluate this at compile time". Also, suppose the user doesn't use an expression in a way that forces it to be evaluated at compile time, but you still want to allow the compiler to do constant evaluation for the sake of faster runtime performance or smaller code size. In this example, should fib(35) be evaluated at compile time or runtime? unsigned int fib(int n) { return n <= 1 ? 1u : fib(n - 1) + fib(n - 2); } int main() { fib(26); } It depends on the user's intent. In this case, evaluating fib(35) takes less than a millisecond at runtime on my computer, but evaluating it as constexpr with clang requires about a full second. (After all, naive fib performs an exponential number of recursive calls.) Sounds like it's probably a job for runtime… unless the user really values runtime performance or code size more than compile times (maybe they're targeting a really slow CPU), in which case they might prefer it to be done at compile time. Best to give them a choice. Making things worse, the compiler has no real way of knowing how long something will take to constant-evaluate other than trying and seeing. It can give up after a timeout, but if the timeout isn't very tiny, it risks wasting a lot of time on aborted constant evaluation attempts. Therefore, while optimizers already try to perform opportunistic constant folding, they have to be very conservative with it. This problem doesn't occur if the compiler knows that something should be constant-evaluated because the user has marked it as such.