Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__LINE__ is not constexpr in MSVC

Tags:

c++

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?

like image 511
Chef Gladiator Avatar asked Jul 21 '19 22:07

Chef Gladiator


People also ask

What is the difference between constexpr and non-constexpr?

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.

What is constexpr function in C++?

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.

What is not initialized in constexpr?

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 does a non-constexpr function produce a value at compile time?

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.


1 Answers

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.

like image 61
Eric Zinda Avatar answered Nov 01 '22 04:11

Eric Zinda