__LINE__ is not constexpr in MSVC - c++

Update 28NOV2022
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31933 for x86
This issue seems to be sorted.
Original Post
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?

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.

Apparently, this is already a known issue by the MSVC community:
We have a known bug for this issue on the C++ team here. The status on this Developer Community item will be updated as that bug is looked at. Thanks again for reporting this to us.
Apparently, it is considered a "feature" of the compiler:
The bug is considered a feature: Edit-and-Continue has a small but vocal and enthusiastic group of users (mostly game developers)
A user in the linked thread offers the following as a workaround:
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define USABLE_LINE int(CAT(__LINE__,U))
//appending 'U' shouldn't change much as __LINE__ is supposedly non-negative anyway

Related

Why does __LINE__ not work with this consteval function? [duplicate]

Update 28NOV2022
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31933 for x86
This issue seems to be sorted.
Original Post
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?
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.
Apparently, this is already a known issue by the MSVC community:
We have a known bug for this issue on the C++ team here. The status on this Developer Community item will be updated as that bug is looked at. Thanks again for reporting this to us.
Apparently, it is considered a "feature" of the compiler:
The bug is considered a feature: Edit-and-Continue has a small but vocal and enthusiastic group of users (mostly game developers)
A user in the linked thread offers the following as a workaround:
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define USABLE_LINE int(CAT(__LINE__,U))
//appending 'U' shouldn't change much as __LINE__ is supposedly non-negative anyway

Trying out [[nodiscard]] with no success

I am trying to test a little C++17. I am trying to do:
[[nodiscard]] int get_value1()
{
return 42;
}
inline void start()
{
// Should generate warning
get_value1();
}
However, it does not. I am using Visual studio 2017. Warning level set to Level4(\W4). I have set C++ Language Standard to ISO C++ Latest Draft Standard (/std:c++latest).
But it does not generate the warning that I want. Why is that? Also, a little side question: That tab to select the language standard only appears in Debug configuration and not Release. Why is that? Release complains on the nodiscard, Would that mean that Release is in C++14?
edit: naturally I meant warning in the second section. Corrected. :)
Actually [[nodiscard]] is supported only since VS 2017.3 and it should give you a warning, not an error. And as I understand specification assumes that compiler may warn you. And may not.

error C4146: unary minus operator applied to unsigned type, result still unsigned

I try to build CRF++ in Visual Studio 2013 and get this error in the last line:
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-siblings[i].left-1);
error C4146: unary minus operator applied to unsigned type, result
still unsigned
Specifically, it is in darts.h, line 189.
I built again in Visual Studio 2015 then there is no error.
How can I fix this in Visual Studio 2013?
C4146 is not supposed to be an error. It is a mere warning. If you see it as an error in your case, it means that someone has configured it this way, most likely unintentionally. This makes no sense.
Find and undo the changes that turned it into an error. Then you can disable it if you wish.
For others I wanted to add another answer in case they stumble into that bug like me.
Even if "Threat warning as error" was off in my compiler, I had to compile my project with #pragma warning(disable:4146) in my header's file that was showing me the error. For you it would had been inside darts.h
Please note disabling the warning globally in my project was not working (compiler /wd4146), the pragma line was needed in the header's file directly.
the siblings variable also has unary minus applied to it, maybe that is the culprit? Also if it's templated code you cannot really be sure value_ is going to be be short, int or long unless that is asserted via static_assert or so. We can only guess as you don't provide information about what types are actually used or something reproducable. Also did you use the exact same project for compilation in VS2015? If not, the warning might just have been disabled there.
Anyway, suppose it is a bug in VS2013, it likely won't ever get fixed anymore so you can try to find a workaround. Start by breaking that statement down into smaller ones until you know exactly which part is the problem (or maybe, by then the problem is gone already as it goes with compiler bugs). Then suppress the warning with #pragma warning ( disable : 4146 ), wrapped in a conditional directive so it only has effect for VS2013 #if _MSC_VER > 1800 && _MSC_VER < 1900 should do fine. Enable the warning again after the statement. Add a comment as to why the warning is disabled and submit the changes as a patch to CRF++.
Try this:
int tmp = static_cast<int>(siblings[i].left);
array_[begin + siblings[i].code].base =
value_ ?
static_cast<array_type_>(-value_[siblings[i].left]-1) :
static_cast<array_type_>(-tmp - 1);
For anyone running into the really confusing part of this:
This isn't supposed to be an error. In fact, there are a bunch of warnings that Visual Studio incorrectly turns into errors by default. Compilers can add warnings for whatever they want, but throwing errors for valid code is just a bug.
The culprit is the "SDL checks" option. It's known for adding things like runtime stack checking, which is fine, but they snuck a bit of nastiness in: "and enables extra security-relevant warnings as errors". That needs to be turned off to have something slightly closer to a standard C++ compiler.

fatal error C1017: invalid integer constant expression when using "#if (false)"

Have following code which is working under Linux but gives error for MSVS
#if (false)
....
#endif
The error is: fatal error C1017: invalid integer constant expression
I found this report on Microsoft's web:
http://msdn.microsoft.com/en-us/library/h5sh3k99.aspx
While the info described there differs a little bit compared to my case as I didn't use the "#define"
So my question is:
Is there any way to make it working for MSVC without changing code ?
If the code must be updated, what's the best solution for this kind of case?
It looks like your version of MS compiler does not support false as a built-in constant. This is not surprising, because Microsoft has a spotty record of supporting standards for C and C++.
One way to make this work without changing the code is to pass command-line parameters to the compiler to define false as 0 and true as 1:
-Dfalse=0 -Dtrue=1
Is there any way to make it working for MSVC without changing code ?
Not really. Defining a macro for false is forbidden by the standard for good reasons, [macro.names]/2:
A translation unit shall not #define or #undef names lexically
identical to keywords, to the identifiers listed in Table 3, or to the
attribute-tokens described in 7.6.
And I don't see any other way.
If the code must be updated, what's the best solution for this kind of
case?
Substitute 0 for false.

alignas(T) not resolved in template function

When use Eclipse with MinGW(version:4.8.1) to compile the following code fragement, it can pass but Eclipse still report:
"Multiple markers at this line - Type 'alignas' could not be resolved"
template<typename X> void set_aside(std::vector<X> vx) {
constexpr int max_buf = 1024;
alignas(X) X buffer[max_buf];
int max = min(vx.size(), max_buf / sizeof(X));
std::uninitialized_copy(vx.begin(), vx.begin() + max, buffer);
}
What happend with this issue, although the code fragement pass the comiple,yet Eclipse marks with error.
Someone have ever met this issue? Please kindly help me to resolve this issue,thanks very indeed!
Many IDEs use a front-end syntax checker that is different than their back-end compiler. Eclipse Kepler (released June 2013) is mostly up-to-date with C++11 syntax, although some things like alignment support and the interaction with in-class initializers and default constructors might not be fully supported (yet). Similary, C++14 features like decltype(auto) will work if the back-end compiler is called with std=C++1y but will not be recognized by the front-end syntax checker.
NOTE: this is not unique to Eclipse, also Visual C++ Intellisense is sometimes running behind (especially in CTP versions) the actual compiler, causing the red squiggly lines.