ok, the latest VS 2019 Community, local "all defaults" C++ console project:
int main()
{
// cl Version 19.21.27702.2 for x86
//
constexpr auto MSCVER = _MSC_VER; // 1921
constexpr auto MSCFULLVER = _MSC_FULL_VER; //192127702
constexpr auto MSCBUILD = _MSC_BUILD; // 2
/*
: error C2131: expression did not evaluate to a constant
: message : failure was caused by non-constant arguments or reference to a non-constant symbol
: message : see usage of '__LINE__Var'
*/
constexpr auto LINE = __LINE__;
}
But. Seemingly the same compiler on Godbolt compiles this ok. As ever before.
https://godbolt.org/z/rn44rN
Any idea?
The Status as of 2019-07-22
Apparently, this is a bug which is a feature. Ugh. And there is a macro which is almost perfect, besides the fact it casts to int, and the type of the LINE is long. Here is my version:
#define _DBJ_CONCATENATE_(a, b) a ## b
#define _DBJ_CONCATENATE(a, b) _DBJ_CONCATENATE_(a, b)
#define CONSTEXPR_LINE long(_DBJ_CONCATENATE(__LINE__,U))
Original is here. I had almost the same solution, but I was adding a zero instead of U. Perhaps because I spent hours trying to figure out what is going on.
I am sorry, but the reasoning of the MSVC team on that page is just strange. I am wondering is there a detail in the standard which resolves this issue.
Many thanks to commenters for pointing me in the right direction. But there is this remaining mistery: How come Godbolt + MSVC, has no problems with this same code?
When its arguments are constexpr values, a constexpr function produces a compile-time constant. When called with non-constexpr arguments, or when its value isn't required at compile-time, it produces a value at run time like a regular function.
constexpr functions. A constexpr function is one whose return value can be computed at compile time when consuming code requires it. Consuming code requires the return value at compile time, for example, to initialize a constexpr variable or provide a non-type template argument.
Not initialized int j = 0; constexpr int k = j + 1; //Error! j not a constant expression A constexpr function is one whose return value is computable at compile time when consuming code requires it. Consuming code requires the return value at compile time to initialize a constexpr variable, or to provide a non-type template argument.
When called with non- constexpr arguments, or when its value isn't required at compile time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write constexpr and non- constexpr versions of the same function.) A constexpr function or constructor is implicitly inline.
The MSVC team points out in that link that if you change the "Debug Information Format" from "/ZI" (Program Database for Edit and Continue) to "/Zi" (Program Database) this also fixes it (but disables edit and continue). It worked for me.
If you're not using Edit and Continue this seems like the right fix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With