Live data from Hacker News

C++17 constexpr everything, or as much as the compiler can

solarianprogrammer.com

21–30 of 120 posts

Re: C++17 constexpr everything, or as much as the compiler can

#21
post #2

What about debugging? If the code to generate the data is large and complex, how do you debug it when it only runs at compile time? Is the solution to start with two programs like the author and then merge them? That still seems like a maintainability issue.

> ...how do you debug it when it only runs at compile time?

I prefer to unit test my constexpr logic with a bunch of static assertions in a cpp file. You could put them in with the code being debugged, but having them separate keeps the header files lighter weight with no real downside assuming you have CI or something set up.

Re: C++17 constexpr everything, or as much as the compiler can

#22
post #19

>In conclusion, at the time of this writing, you need to inspect the generated code of your compiler, if you want to be sure that something is really calculated at compile time. I don't get this. Why? Doesn't making a variable constexpr ensure it is a compile time value, or it will fail to compile?

Apparently constexpr is like "inline". Just as the inline keyword doesn't actually guarantee that the compiler will inline a function, so constexpr doesn't require the compiler to precompute something, but rather just gives a hint to the compiler that you'd like it to if it can.

Re: C++17 constexpr everything, or as much as the compiler can

#23
post #17

C++ is never just C++. The build system for any C++ program includes both macro language and some form of make and/or make replacement. Explicitly generating tables at compile time and linking is bog standard at this point. Write a table generator program, have output create a table, splice in the order into make and/or make replacement. Sure it's three extra steps, but it's small steps that can be debugged. It also…

And have all embedded engineers raging because you just made cross compilation an order of magnitude harder.

The secret there, of course, is not to write the table generation program in C++. (-:

In such circumstances, I find myself writing the table generator in shell script, REXX, or some such convenient language on the host system.

Re: C++17 constexpr everything, or as much as the compiler can

#24
post #19

>In conclusion, at the time of this writing, you need to inspect the generated code of your compiler, if you want to be sure that something is really calculated at compile time. I don't get this. Why? Doesn't making a variable constexpr ensure it is a compile time value, or it will fail to compile?

There might be a case where you expected the compiler to constexpr something but it didn't. I can imagine cases where a heavy function getting called more than once, because you had expected it to be pre-computed.

Re: C++17 constexpr everything, or as much as the compiler can

#25

All of this is easy in Common Lisp, which includes interactive compile-time debugging. You can use #., EVAL-WHEN, LOAD-TIME-VALUE, and other things to control evaluation time, and use the same, usual, interactive debugger that you use for runtime code, without any extra infrastructure or scaffolding. In C++, to debug failed constexpr’s, often, you have to make it a non-constexpr and debug at runtime.

or you can just use a C++ repl like Cling ?

Re: C++17 constexpr everything, or as much as the compiler can

#26
post #19

>In conclusion, at the time of this writing, you need to inspect the generated code of your compiler, if you want to be sure that something is really calculated at compile time. I don't get this. Why? Doesn't making a variable constexpr ensure it is a compile time value, or it will fail to compile?

Literally the second example shows a failing case for Clang 5 where GCC is able to statically compute it at compile time.

Re: C++17 constexpr everything, or as much as the compiler can

#27

I'm not sure this is really necessary. gcc and Apple's clang optimize the factorial code without "constexpr" and the fibonacci code might be an extreme case avoided by reasonable defaults for the numerous optimization parameters that can be adjusted: max-inline-recursive-depth max-inline-recursive-depth-auto Specifies the maximum recursion depth used for recursive inlining. For functions declared inline, --param max-…

You should watch the talk that's mentioned in the article. They demo a constexpr json parser and a constexpr regex engine.

Re: C++17 constexpr everything, or as much as the compiler can

#28
post #3

Earlier quoted context omitted.

You could use something like #ifdef NDEBUG #define MY_CONSTEXPR #else #define MY_CONSTEXPR constexpr so when you are running the debug build, everything is debuggable.

That makes the compiler not complain when your constexpr isn't a valid constexpr.

Until you make release

Re: C++17 constexpr everything, or as much as the compiler can

#29
post #20

C++ is never just C++. The build system for any C++ program includes both macro language and some form of make and/or make replacement. Explicitly generating tables at compile time and linking is bog standard at this point. Write a table generator program, have output create a table, splice in the order into make and/or make replacement. Sure it's three extra steps, but it's small steps that can be debugged. It also…

Why do you say writing auxiliary programs and tools to integrate the data is "standard practice", and a simple and straightforward language feature are "advanced compiler tricks"?

Because 'generate a table by having make run a simple program' is something people have done for decades with C, C++ and other languages, whereas constexpr is a new feature that's only just appeared in the C++ language spec and apparently silently degrades to "not actually at compile time".

Re: C++17 constexpr everything, or as much as the compiler can

#30
post #22
post #19

>In conclusion, at the time of this writing, you need to inspect the generated code of your compiler, if you want to be sure that something is really calculated at compile time. I don't get this. Why? Doesn't making a variable constexpr ensure it is a compile time value, or it will fail to compile?

Apparently constexpr is like "inline". Just as the inline keyword doesn't actually guarantee that the compiler will inline a function, so constexpr doesn't require the compiler to precompute something, but rather just gives a hint to the compiler that you'd like it to if it can.

constexpr means you CAN use the function in a constant expression

inline means you CAN define a function in multiple translation units without violating ODR

no guarantees in the other direction

Post reply on HN