Consider this program:
#include <iostream>
template<bool Debug = false, int Line = __LINE__>
constexpr int adds(const int& a, const int& b) {
if (Debug)
std::cout << __FUNCTION__ << " called on line " << Line << '\n';
return (a + b);
}
int main() {
std::cout << adds(3, 7) << '\n';
std::cout << adds<true, __LINE__> (5, 9) << '\n';
return 0;
}
When I try to compile and build this in Debug
mode Visual Studio 2017 is generating these compiler errors:
1>------ Build started: Project: Simulator, Configuration: Debug x64 ------
1>main2.cpp
1>c:\***\main2.cpp(12): error C2672: 'adds': no matching overloaded function found
1>c:\***\main2.cpp(12): error C2975: 'Line': invalid template argument for 'adds', expected compile-time constant expression
1>c:\***\main2.cpp(3): note: see declaration of 'Line'
1>Done building project "Simulator.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
However, when I try this under Release
mode: It compiles, builds, runs, and produces the appropriate output:
10
adds called on line 12
14
Is this a potential Visual Studio 2017 bug? If not, why does it work in one mode and not the other?
You can see it compiled here: Compiler Explorer
Here's a copy of the command line flags for both debug and release modes:
Debug
/JMC /permissive- /GS /W3 /Zc:wchar_t /Qspectre /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc141.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Simulator.pch" /diagnostics:classic
Release
/permissive- /GS /GL /W3 /Gy /Zc:wchar_t /Qspectre /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc141.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /std:c++latest /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\Simulator.pch" /diagnostics:classic
You can now debug your release build application. To find a problem, step through the code (or use Just-In-Time debugging) until you find where the failure occurs, and then determine the incorrect parameters or code.
By default, Debug includes debug information in the compiled files (allowing easy debugging) while Release usually has optimizations enabled. As far as conditional compilation goes, they each define different symbols that can be checked in your program, but they are language-specific macros.
Visual Studio projects have separate release and debug configurations for your program. You build the debug version for debugging and the release version for the final release distribution. In debug configuration, your program compiles with full symbolic debug information and no optimization.
Select the Properties icon (or press Alt+Enter ). In the side pane, choose Build (or Compile in Visual Basic). In the Configuration list, choose Debug or Release.
Set debug and release configurations in Visual Studio. Visual Studio projects have separate release and debug configurations for your program. You build the debug version for debugging and the release version for the final release distribution. In debug configuration, your program compiles with full symbolic debug information and no optimization.
If your Release Mode problem is caused by code being unintentionally removed. It is very likely that you can reproduce the problem in debug mode. Some problems can be caused by differences during preprocessor symbols used to compile Debug and Release projects.
You can make your Debug compile more like a release compile by making the following changes: In Project Settings (Alt-F7) under the C++/C tab, set the category to "General" and change the "_DEBUG" preprocessor definition to "NDEBUG".
Seems like it was reported: __LINE__
cannot be used as an argument for constexpr functions.
We have a known bug for this issue on the C++ team here.
[...]
We have determined that this issue is not a bug. Please refer to comments of Jonathan.
And Jonathan says:
This is a side-effect of the compilers support for Edit-and-Continue (basically we don't want a change to the value of
__LINE__
to be considered a 'rude' edit that suppresses Edit-and-Continue): if you compiler with/Zi
instead of/ZI
then the code should compile (but the executable won't support Edit-and-Continue).
[...]
The bug is considered a feature ...
From MSVC docs:
The
/ZI
option is similar to/Zi
, but it produces a PDB file in a format that supports the Edit and Continue feature. [...] The/ZI
option is also incompatible with use of the__LINE__
predefined macro; code compiled with/ZI
can't use__LINE__
as a non-type template argument, although__LINE__
can be used in macro expansions.
However, when I try this under Release mode: It compiles, builds, runs, and produces the appropriate output:
I guess the reason for it is the /ZI
vs /Zi
flag difference. Your release mode flags have /Zi
so it compiles fine.
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