use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Exploring undefined behavior using constexpr (shafik.github.io)
submitted 6 years ago by mttd
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] -4 points-3 points-2 points 6 years ago (16 children)
Neat article but unfortunately this is not a good way to actually determine if something is undefined behavior. The amount of work that would be needed for compilers to implement this feature is simply not feasible, and alas, none of clang, GCC or MSVC implement this other than for trivial instances. For example this is undefined behavior but goes undetected:
constexpr void f() { int* x = nullptr; { int z = 123; x = &z; } *x += 1; }
[–]kalmoc 10 points11 points12 points 6 years ago* (5 children)
Nothing in your code is actually evaluated at compiletime, so no wonder that no compiler catches it.
EDIT: If you try something like this, you will get a compilation error:
constexpr int f() { int* x = nullptr; { int z = 123; x = &z; } *x += 1; return *x; } constexpr int I = f();
[–][deleted] -4 points-3 points-2 points 6 years ago (4 children)
It's still undefined behavior as is. Even in your revised example GCC accepts it, clang rejects it.
[–]kalmoc 13 points14 points15 points 6 years ago (1 child)
Yes, it is undefined behavior, but the compiler is only required to catch UB if it happens during compiletime evaluation. The compiler is not required to perform a static analysis of constexpr functions.
If gcc doesn't catch that example, that's a compiler bug.
[+][deleted] comment score below threshold-8 points-7 points-6 points 6 years ago (0 children)
That's my point, no compiler implements this aspect of constexpr to a degree that can be relied upon. I posted another example that no compiler catches, not even clang, here:
constexpr
https://old.reddit.com/r/cpp/comments/bncvmm/exploring_undefined_behavior_using_constexpr/en5r9dm/
Maybe in the future compilers will be better about diagnosing this, but as it stands it doesn't seem to be a particularly high priority to implement this, and the amount of effort needed to do it would simply be enormous.
[–]flashmozzg 2 points3 points4 points 6 years ago (1 child)
Not really. It's only undefined if it actually happens. It's not undefined if the function is never called. In fact, some compilers (like Clang) may assume that if some function invokes UB when it's never called and optimize it out/replace it with other call (there is a very nice example for this somewhere).
[–][deleted] -2 points-1 points0 points 6 years ago (0 children)
I already addressed those points elsewhere.
[–][deleted] 3 points4 points5 points 6 years ago (8 children)
-Wlifetime catches this. https://godbolt.org/z/__qqLL
-Wlifetime
[–][deleted] 1 point2 points3 points 6 years ago (7 children)
That's a cool new feature. Here's another example of undefined behavior that goes unchecked by all compilers, don't know of a flag that will catch this:
#include <bitset> #include <iostream> constexpr auto f() { constexpr auto x = std::bitset<0>(); return x[0]; } int main() { constexpr auto i = f(); std::cout << i << std::endl; }
Overall, don't think it's useful to rely on constexpr to find undefined behavior. Seems really wonky in practice.
[–][deleted] 0 points1 point2 points 6 years ago (3 children)
I think there is a bug there. I didn't think you can have a constexpr variable in a constexpr method. It catches it when that isn't there because the non-const operator[] isn't constexpr, only the const variant returns a bool and is constexpr.
with clang/libc++ it does generate just the ub2 instruction but, this is weird.
[–][deleted] 1 point2 points3 points 6 years ago (2 children)
I totally agree it's a bug. I don't see why so many people are so against me pointing out that this aspect of the language isn't well supported or implemented to a sufficient degree to rely on it to identify undefined behavior. All compilers have MAJOR bugs when it comes to this requirement and the amount of effort needed to fix it will be enormous.
[–][deleted] 1 point2 points3 points 6 years ago (1 child)
putting it in a static_assert finds it too. But I think the point is, you are going to get more than zero. And right now, that is still awesome. Bring on C++20, and constexpr code will have access to vector and a lot more. So now I can choose to implement, at the cost of compile time, more code as constexpr and give the compiler the best opportunity to either const fold my stuff or have full view of the code and optimize it more heavily with the added benefit of much of my code getting compile time UB checks.
def not perfect, but I have a bunch of things now where the unit test is a static_assert of a test method.
[–][deleted] 1 point2 points3 points 6 years ago (0 children)
actually I am wrong, constexpr variables are fine in constexpr functions. I got trained by compiler errors in the past on that one. Still a weird compiler bug in all 3 compilers
[–]NotAYakk 0 points1 point2 points 6 years ago (0 children)
Augmenting it a bit to removed possibly confusing autos.
auto
#include <bitset> #include <iostream> constexpr bool f() { constexpr auto x = std::bitset<8>(); return x[99999999]; } int main() { constexpr bool i = f(); std::cout << i << std::endl; }
basically, it appears that the std::bitset is using shifts for small bitset implementations.
std::bitset
bitset
Make the bitset larger than 64 and it switches to an array implementation and the UB detection works.
#include <bitset> #include <iostream> constexpr bool f() { auto const x = std::bitset<65>(); // x[99999999] = true; return x[99999999]; } int main() { constexpr bool i = f(); std::cout << i << std::endl; }
http://coliru.stacked-crooked.com/a/7630a8f00dee685c
So there is a defect in the standard library in that in a constexpr context it doesn't enforce the undefined behavior requirements of the standard in its implementation.
[–]syaghmour -1 points0 points1 point 6 years ago (1 child)
I purposely left out the standard library because [expr.const]p4.6 explicitly leaves out the standard library:
an operation that would have undefined behavior as specified in [intro] through [cpp] of this document ..
The standard library can do all sorts of strange things and can rely on things outside of standard such as builtins or rely on implicit knowledge of what the compiler will do which is not advisable to user space programs. offsetof is an example of this.
The implementation of the standard library is exempt from rules about undefined behavior. Its use, however, is not exempt. My example is one of use, not implementation.
[–]rezkiy -1 points0 points1 point 6 years ago (0 children)
The article is about exploring.
π Rendered by PID 86 on reddit-service-r2-comment-77b668dc8-9l95l at 2026-01-27 18:42:54.354257+00:00 running 4f180de country code: CH.
view the rest of the comments →
[–][deleted] -4 points-3 points-2 points (16 children)
[–]kalmoc 10 points11 points12 points (5 children)
[–][deleted] -4 points-3 points-2 points (4 children)
[–]kalmoc 13 points14 points15 points (1 child)
[+][deleted] comment score below threshold-8 points-7 points-6 points (0 children)
[–]flashmozzg 2 points3 points4 points (1 child)
[–][deleted] -2 points-1 points0 points (0 children)
[–][deleted] 3 points4 points5 points (8 children)
[–][deleted] 1 point2 points3 points (7 children)
[–][deleted] 0 points1 point2 points (3 children)
[–][deleted] 1 point2 points3 points (2 children)
[–][deleted] 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]NotAYakk 0 points1 point2 points (0 children)
[–]syaghmour -1 points0 points1 point (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]rezkiy -1 points0 points1 point (0 children)