constexpr errors; VS2017 C++ compiler regression? - c++

Just installed VS2017, which claims to have superior C++14 support since 2015 (which was rudimentary).
Gave it a spin on one of my projects which uses constexpr, and noticed what appear to be some regressions.
This code:
struct s
{
size_t i;
constexpr s(nullptr_t) noexcept : i(0) {}
};
static_assert(s(nullptr).i == 0, "!!");
Compiles no problem on VS2015 and Clang, but I get a new error in VS2017:
error C2131: expression did not evaluate to a constant
note: failure was caused by unevaluable pointer value
note: while evaluating 's::s(&s{(null)})'
This code looks fine right? Is constexpr meant to have a problem with nullptr?
I'm astonished a regression this basic could appear, I suspect there must be something wrong with my code...

constexpr constructor(std::nullptr_t) causes "error C2131: expression did not evaluate to a constant"
This issue was reported as a bug in Visual Studio 2017 version 15.1.
There was a variation of another issue reported earlier by the OP (?).
This was fixed in: Visual Studio 2017 version 15.6 Preview 1

Related

Compile error with constexpr functions (visual studio 2015)

I am trying to compile the following piece of code in Visual Studio 2015 (Community version) but encountering the error shown further down below.
/*****Source Code Start*******/
constexpr char const* GetStatusAsCString(Status compute)
{
switch (compute)
{
case armnn::Status::Success: return "Status::Success";
case armnn::Status::Failure: return "Status::Failure";
default: return "Unknown";
}
}
/*****Source Code End*******/
Error message:
> Error (active) a constexpr function must contain exactly one return
> statement ArmNN_MnistTF_64b c:\armnn\armnn-devenv\armnn\include\armnn\TypesUtils.hpp 22
Note that i have made sure of the following settings:
Set the compiler front end as Clang in VS 2015:
I have set the C++ standard as C++14.
Can anyone please advise me on what else am I missing? Been struggling with this error for sometime now.
Visual Studio 2015 does not fully implement C++14 even as of VS 2015 Update 3 although it has a lot of it.
Specifically, N3652 Extended constexpr is not implemented until VS 2017. You should upgrade to the latest VS 2017 Community edition update (which at this point is 15.7)
See Visual C++ Language Conformance

Error C1903 - unable to recover from previous errors when calling offsetof

I have a weird error when I compile my project on MSVC.
I am using Microsoft Visual Studio 15 2017 and I compile in c++17 (MSVC version 15.6.85.37198)
The code compiles on Clang and G++ but it gives me an error on MSVC.
I managed to reduce the code causing the error to the following snippet :
#include <cstddef>
struct Point {
double x;
double y;
double z;
};
template<class... Ps>
void doSomething() {
offsetof(Point, x);
}
int main() {
doSomething();
}
It gives me the following error :
main.cpp(10): fatal error C1903: unable to recover from previous error(s); stopping compilation [build\example.vcxproj]
I was a bit puzzled at first since it was the only error and it took me quite some time before I could identify that the problem came from offsetof.
The problem come from using the offsetof macro inside a templated function that takes a parameter pack in.
I do not think this code is doing anything illegal or is using undefined behavior. So, is the problem on my end or is it a bug in the compiler ?
Thanks
Since Point is a standard layout type, the use of offsetof(Point, x) is well-defined.
The fact that MSVC17 fails to compile your minimal example is surely a bug due to its incapability to support template parameter packs completely.

Warnings not being generated in VS2017

It seems to me that VS2017 fails to catch some fairly obvious compiler warnings which older versions do not. This seems so fundamental to me that I'm guessing the problem has to be something I'm missing (e.g. some new default compiler setting, perhaps?). Has anyone else seen this?
To test this, I create a simple console application in both 2013 and 2017. The only change I made the to the project settings was to set the compiler warning level to 4 and to report warnings as errors. Below is the entirety of the source
In VS2013 this fails. In 2017, it builds just fine...
// TestWarning4127.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
int main()
{
if (true) // *** SHOULD generate warning 4127
std::cout << "Warning";
return 0;
}
Am I missing something obvious here...?
When used inside an if or while conditions the trivial constants such as 1 or true do not generate warnings in VS 2017 as described in the Compiler Warning (level4) official documentation. Excerpt from the official documentation:
The controlling expression of an if statement or while loop evaluates
to a constant. Because of their common idiomatic usage, trivial
constants such as 1 or true do not trigger the warning, unless they
are the result of an operation in an expression.
That being said it's not a warning in VS 2013 with the default warning levels of W3 either. Only with the elevated W4 settings does the VS 2013 report a warning. It was removed in VS 2017 altogether.
For comparison, the GCC does not generate the warning either:
Live example on Coliru.

C++11 constexpr causes compiler's internal error (C1001)

I am using Visual Studio 2015 Update 3.
I get a fatal error:
(code C1001) : An internal error has occurred in the compiler.
Here is the code :
template<typename T>
constexpr T epsilon = std::numeric_limits<T>::epsilon();
I read it was fixed in Visual Studio Update 2. Can someone explain me why I am getting this error? Thanks in advance.
Any internal error (ICE) is a compiler bug. You get it because you have happened to trigger that bug. For this compiler you can report it at Microsoft Connect.
For such a report you need an example with an expected correct result, and the erroneous result.
The following test program compiles & runs nicely with MinGW g++ 5.1
#include <limits>
template<typename T>
constexpr T epsilon = std::numeric_limits<T>::epsilon();
#include <iostream>
using namespace std;
auto main() -> int
{
cout << epsilon<double> << endl;
}
Output:
2.22045e-016
With Visual C++ 2015 update 2 it produces an ICE:
foo.cpp(10): fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\symbols.c', line 28114)
To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
foo.cpp(10): note: see reference to variable template 'const double epsilon' being compiled
Compiler version:
> cl /nologo- 2>&1 | find "++"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86
I've raised this as a bug with Microsoft, but they have had a fix since early 2017 which has not been released from what I can see as of today.
I've also provided a project on GitLab and given information to Microsoft for this project here: https://gitlab.com/cppocl/tostring
Loading the .sln and compiling currently crashes with Visual Studio 2015 update 2 or 3, and Visual Studio Enterprise 2017 version 15.3.1.
It does seem that the combination of template and constexpr causes the compiler to crash.
I've seen reports for Visual Studio 2017 describing similar types of problems.
This link says fixed pending release:
https://developercommunity.visualstudio.com/content/problem/18155/msvc-2017-c-fatal-error-c1001-constexpr-initializa.html
Visual Studio 2015 backlog of bugs relating to constexpr is here:
https://blogs.msdn.microsoft.com/vcblog/2015/12/02/constexpr-in-vs2015-update-1/
EDIT:
I also don't believe changing optimization settings will make any difference, as has been recommended in other posts.
I have experimented with these settings and applied recommended patches without success so far.

Visual C++ syntax error for pointer reference initialization

Why does Visual C++ 2008 give a syntax error for the following code?
int* x;
int*& xalias(x); //error C2061: syntax error : identifier 'x'
Is this simply a bug? (gcc and clang accept this...)
Do later versions of Visual Studio fix this, or should I just work around this as below?
int*& xalias = x;
Your workaround is fine, and yes it is a bug in Microsoft's C++ compiler. Here is the bug report submitted to Microsoft. They don't appear in a hurry to fix it as there is a trivial work around, as you found yourself.