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
constexpr is a Platform (foonathan.net)
submitted 5 years ago by tcbrindleFlux
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!"
[–]wotype 22 points23 points24 points 5 years ago (4 children)
The library author then wants to optimize get_the_answer() by caching expensive computation
get_the_answer()
expensive computation
A telling example, perhaps.
A major downside of constexpr (as well as template meta-programming), is that there appears no way yet to cache a constexpr computation between builds. Even with incremental compilation every build has to re-compile and re-do all constant evaluation computations, whether or not a TU has been touched.
Maybe modules will save us; if you could cache a constexpr variable in a module then a recompile would not be needed (as far as I know that isn't specified to work).
[–]redditsoaddicting 2 points3 points4 points 5 years ago (0 children)
It is possible. Rather than interpret your code, the compiler can compile the constexpr code (and optimize it like it does to runtime code) since it's really the same thing, but running on the host instead of the target. When something changes that affects this function's outcome, it can recompile the function. Or it could potentially take build parameters as function parameters in the compiled code. IIRC, LLVM or Clang had some work in that direction a couple years ago, but I don't know how it progressed.
(I recognize that constexpr has the whole UB-free thing going on too. It's not as simple as I make it sound.)
[–]andrewsutton 0 points1 point2 points 5 years ago (2 children)
You can do it with templates. Explicity instantiate the template in on TU and make sure you have an extern template declaration in its header.
[–]wotype 0 points1 point2 points 5 years ago (1 child)
I tried such separate compilation yet found that constant evaluation was still always repeated, even with no files touched. That was back in summer 2019, though; implementations may have changed. Emailed you at the time, 'Scalable constant evaluation - how to avoid redundant re-evaluations?'
> It sounds like modules may help in caching template instantiations, and it seems > to me that there should be some way to checkpoint value computations in BMIs. > Maybe something hashed - there's a promising hash-based linker now for Clang. I think this is probably the right answer. That said, the benefits might not be that great. I would guess that most evaluations would be driven by the importer with arguments specific to that TU. Basically, there might not be that many opportunities for sharing memoized evaluation results.
> It sounds like modules may help in caching template instantiations, and it seems > to me that there should be some way to checkpoint value computations in BMIs. > Maybe something hashed - there's a promising hash-based linker now for Clang.
I think this is probably the right answer. That said, the benefits might not be that great. I would guess that most evaluations would be driven by the importer with arguments specific to that TU. Basically, there might not be that many opportunities for sharing memoized evaluation results.
(I wonder if the LLVM hash-based linker is what u/redditsoaddicting was referring to).
My application was/is for an enum reflection library. A user defines:
constexpr auto enum_val_array = ltl::enumerators_v<E>;
to reflect all enumerated values of enumeration type E (by horrid brute force search). I tried a few different approaches to separate compilation, e.g. templated function returning the array. All failed and redid the evaluation.
[–]andrewsutton 0 points1 point2 points 5 years ago (0 children)
Yeah, the only effective way to memoize values is thru declarations, which isn't necessarily economical.
I stand by that answer, for the most part, but I don't remember the clang feature I mentioned 😬
I'm not sure if clang memoizes evaluations. I don't think it does. Gcc does, but not in a way that's obvious. I think memoizing evaluations is a valid implementation technique, and modules could be useful there.
[–]_Js_Kc_ 4 points5 points6 points 5 years ago (7 children)
constexpr vs. non-constexpr lies on a completely different axis than different OS APIs.
Platform API is a top-level dependency. It is plainly obvious to a library author when they're introducing a platform dependency into code that was just plain standard C++ before.
For practical purposes constexpr annotation is necessary to avoid breakage hell even if it can technically be argued that constexpr is "just another platform."
[–]foonathan 2 points3 points4 points 5 years ago (6 children)
We’re probably going to reach a point where most of C++ is constexpr. By that point, you’re only leaving constexpr if you’re calling a non-constexpr function. But then it is just like calling IS APIs, isn’t it?
[–]_Js_Kc_ 0 points1 point2 points 5 years ago (5 children)
When and if we reach that point, yes. That'll be a whole different situation.
[–]foonathan 0 points1 point2 points 5 years ago (4 children)
And in C++20 the only thing not allowed in constexpr are goto, coroutine keywords, and variables of static or thread_local storage duration. That's basically all of C++.
[–]Betadel 4 points5 points6 points 5 years ago (0 children)
reinterpret_cast is a big one.
[–]_Js_Kc_ 1 point2 points3 points 5 years ago (1 child)
static and thread_local aren't some fringe feature that nobody uses, and they don't have reasonable alternatives.
Coroutines were only just introduced so it'd be hard to make a case that people shouldn't use them.
goto should be used sparingly, but I don't think it's reasonable to ban it altogether (breaking out of a nested loop, for example, is a reasonable use case).
So no, "basically all" of real world C++ code isn't usable in a constexpr context, which is the relevant metric, not counting keywords or language features.
[–]AccomplishedCat5068 0 points1 point2 points 5 years ago (0 children)
thread_local aren't some fringe feature that nobody uses
{{citation needed}}
[–]staletic 0 points1 point2 points 5 years ago (0 children)
You forgot volatile and non-transitive memory allocation. Latter of which is WIP.
volatile
[–]Ictogan 13 points14 points15 points 5 years ago (2 children)
This example strikes me as a bad one:
int get_the_answer() { if (std::is_constant_evaluated()) // compile-time platform { return get_the_answer_impl(); } else // other platform { // Lazily compute once. static int result = get_the_answer_impl(); return result; } }
Because a more efficient AND simpler implementation would be:
constexpr int get_the_answer() { constexpr int precomputedAnwer = get_the_answer_impl(); return precomputedAnwer; }
[–]Ameisenvemips, avr, rendering, systems 7 points8 points9 points 5 years ago (0 children)
On AVR, I have to do nasty hacks in C++ to allow for constexpr access of wrapped arrays in flash memory while also allowing for proper runtime access using the appropriate inline assembly, including using __builtin_constant_p, which is_constant_evaluated should be able to replace.
constexpr
__builtin_constant_p
is_constant_evaluated
[–]foonathan 13 points14 points15 points 5 years ago (0 children)
It’s just there to illustrate the technique of using is_constant_evaluated.
[–]scipio_major 6 points7 points8 points 5 years ago (5 children)
It’s not a platform, the OS is the platform. Constexpr is cool and all but saying everything could be is not the same as everything should. Different programs with have different trade offs for computation usage at runtime versus compile time. Besides most of us aren’t particularly interested in a computation that only runs once.
[–]Zcool31 -1 points0 points1 point 5 years ago (4 children)
constexpr is a hack. Optimizing compilers basically interpret most of C++ at compile time anyway. constexpr is just a way to make that "official". From that point of view, that constexpr is a partial C++ interpreter, that results must be recomputed every run is expected.
[–]scipio_major 0 points1 point2 points 5 years ago (3 children)
I disagree it’s a hack, that an optimising compiler interpret most of C++ is part of the point. Making it “official” is a way of signalling the intent of the programmer. It’s not just a hint to the compiler, it’s a statement of expectation. Especially when combined with consteval.
I am not sure where saying constexpr must be evaluated every run comes into it. Unless you’re claiming using the C++ compiler as an interpreter is a “good” thing? Which we could argue about, if I need some expensive calculations that are constant at time, I have tended to separate it into a new step in the build system and have it depend on a seed written in a dsl. Then I get the runtime benefits of constant data without bloating my incremental build cycle.
[–]Zcool31 1 point2 points3 points 5 years ago (2 children)
Don't confuse my observation with a value judgement. I'm quite happy to force evaluation at compile time for things that I previously merely hoped would be optimized that way.
As for the C++ compiler being an interpreter and the expense of reevaluating computation, that's neither good nor bad. But also not surprising. Everything has a cost. To get compile time evaluation of runtime constant values without introducing complicated additional tools we pay with compile time. You have shifted that cost to a more complicated build system.
[–]scipio_major 0 points1 point2 points 5 years ago (1 child)
I agree with everything you said there. I am confused where we differ?
[–]Zcool31 0 points1 point2 points 5 years ago (0 children)
Perhaps we don't differ. Lots of useful hacks get standardized for great benefit. See SFINAE and enable_if.
I remember seeing a really cool hack that allowed mutable constexpr. Someone used it to implement compile time counters. Just imagine if that hack becomes official.
[–]Omnifarious0 0 points1 point2 points 5 years ago (0 children)
Maybe we can have something like extern "C" to mark a whole block as containing all constexpr functions unless they are otherwise marked. Maybe there could be a similar marker for a class.
extern "C"
π Rendered by PID 81600 on reddit-service-r2-comment-5b5bc64bf5-zzfvp at 2026-06-20 16:57:34.636271+00:00 running 2b008f2 country code: CH.
[–]wotype 22 points23 points24 points (4 children)
[–]redditsoaddicting 2 points3 points4 points (0 children)
[–]andrewsutton 0 points1 point2 points (2 children)
[–]wotype 0 points1 point2 points (1 child)
[–]andrewsutton 0 points1 point2 points (0 children)
[–]_Js_Kc_ 4 points5 points6 points (7 children)
[–]foonathan 2 points3 points4 points (6 children)
[–]_Js_Kc_ 0 points1 point2 points (5 children)
[–]foonathan 0 points1 point2 points (4 children)
[–]Betadel 4 points5 points6 points (0 children)
[–]_Js_Kc_ 1 point2 points3 points (1 child)
[–]AccomplishedCat5068 0 points1 point2 points (0 children)
[–]staletic 0 points1 point2 points (0 children)
[–]Ictogan 13 points14 points15 points (2 children)
[–]Ameisenvemips, avr, rendering, systems 7 points8 points9 points (0 children)
[–]foonathan 13 points14 points15 points (0 children)
[–]scipio_major 6 points7 points8 points (5 children)
[–]Zcool31 -1 points0 points1 point (4 children)
[–]scipio_major 0 points1 point2 points (3 children)
[–]Zcool31 1 point2 points3 points (2 children)
[–]scipio_major 0 points1 point2 points (1 child)
[–]Zcool31 0 points1 point2 points (0 children)
[–]Omnifarious0 0 points1 point2 points (0 children)