Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code using __LINE__ compile under MSVC in Release mode, but not in Debug mode?

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 
like image 695
Francis Cugler Avatar asked Jul 13 '20 06:07

Francis Cugler


People also ask

Can you debug in Release mode?

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.

What is the difference between compiling to debug and Release formats?

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.

What is the difference between debug mode and Release mode 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.

How do I enable debug mode in Visual Studio?

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.

What is debug and release configuration in Visual Studio?

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.

Why can't I debug my project in release mode?

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.

How can I Make my debug compile more like a release compile?

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".


1 Answers

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.

like image 181
Waqar Avatar answered Sep 20 '22 03:09

Waqar