4 ms·
https://en.cppreference.com/w/cpp/language/constant_expression https://en.cppreference.com/w/cpp/language/constant_expressi... Point 8: > A core constant expr
by dgellow 4y ago
https://en.cppreference.com/w/cpp/language/constant_expression https://en.cppreference.com/w/cpp/language/constant_expressi...
Point 8:
> A core constant expression is any expression whose evaluation would not evaluate any one of the following:
> 8. an expression whose evaluation leads to any form of core language undefined behavior (including signed integer overflow, division by zero, pointer arithmetic outside array bounds, etc).
- layer8 4y agoI hope there’s also some text in the standard prohibiting implementations from allowing any other expressions as a constant expression (which they otherwise could as a language extension), and thus requires compilation failure for such expressions?
- kps 4y agoPragmatically, you can't stop extensions; if the fine print for `--std=cool++23` says that this mode is not actually C++23-compliant, nearly nobody will ever notice or care. Pragmatically, if a popular compiler makes `--std=cool++23` the default, and requires `--std=C++23 --iso-eic-jtc1-sc22-wg21 --pompous` to get standard-conforming behaviour, nearly nobody will do that; instead they will complain that other compilers lack the extensions.
- layer8 4y agoExtensions can be standard-compliant, in the sense that they don’t violate any prescription by the standard, and thus a program cannot assume their absence. My question was whether the standard actually takes care to render the acceptance of constexprs-with-UB non-standard-compliant. That is, in addition to “must accept X”, does it also say “must only accept X”?
- tlb 4y agoIndeed, it fails if you invoke UB. For example, an int overflow in a constexpr causes a compile error: <source>:5:17: error: static assertion expression is not an integral constant expression static_assert(1024*1024*1024*3 != 0, "UB"); https://godbolt.org/z/Wc591En7E https://godbolt.org/z/Wc591En7E
- simiones 4y agoThat only works if you know the values at compile-time though: constexpr int foo(int x) { return 1024*1024*1024*x; } int main() { int y; std::cin >> y; static_assert(foo(1)); //all good foo(y); //oops, UB if user enters 7 } https://godbolt.org/z/K8h4Kj99s https://godbolt.org/z/K8h4Kj99s Edit: small correction so that the numbers are big enough to cause problems...
- mgaunard 4y agoTry forcing the call to happen at compile-time. constexpr requires that the function be callable at compile-time, not that it is so.
- tsimionescu 4y agoYou can't call an expression whose value is IO-dependent in a compile-time context, obviously. The tweet seems to imply that if you can call your functions at compile time, they will not present UB at runtime either. I am trying to point out that that is not the case at all.
- mgaunard 4y agoThat seems unrelated to the sub-thread in question.
- tsimionescu 4y agoThe example program is calling foo(y), where the value of y is read from standard input. You suggested to evaluate that expression at compile time, which is not possible. How is this unrelated to the thread?
- mgaunard 4y agoBy forcing the call to happen at compile-time, he would get an error. The input being potentially known at compile-time is not sufficient to make a constexpr function be called at compile-time.
- AshamedCaptain 4y agoThis does not really "guarantee" anything. You can still have as much UB (incl leaks) as you want, as long as they are not evaluated at compile-time. i.e. it's at best equivalent to running valgrind.
- dgellow 4y agoWhat would be examples of runtime UBs that wouldn’t be reported when used within a constexpr?
- simiones 4y agoThe point is that the code is only checked for UB with the arguments it is given at compile time. There is no guarantee that it can't invoke UB with other arguments it might receive at runtime. For example, here is a modification of the original program that does invoke UB, but compiles just fine: https://godbolt.org/z/MaqhcEYqn https://godbolt.org/z/MaqhcEYqn
- dgellow 4y agoOh yes, I see your point. Thanks for clarifying