c++ - 为什么使用 __LINE__ 的这段代码在 MSVC 下可以在 Release 模式下编译,但不能在 Debug 模式下编译?
问题描述
考虑这个程序:
#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;
}
当我尝试在Debug
Visual Studio 2017 模式下编译和构建它时,会生成以下编译器错误:
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 ==========
但是,当我在模式下尝试此操作时Release
:它会编译、构建、运行并生成适当的输出:
10
adds called on line 12
14
这是潜在的 Visual Studio 2017 错误吗?如果不是,为什么它在一种模式下工作而不是另一种?
你可以在这里看到它编译:Compiler Explorer
这是调试和发布模式的命令行标志的副本:
调试
/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
发布
/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
解决方案
好像有人报道过:__LINE__
不能用作 constexpr 函数的参数。
我们在此处的 C++ 团队中有一个针对此问题的已知错误。
[...]
我们已确定此问题不是错误。请参阅乔纳森的评论。
乔纳森说:
这是编译器对 Edit-and-Continue 支持的副作用(基本上,我们不希望对值的更改
__LINE__
被视为抑制 Edit-and-Continue 的“粗鲁”编辑):如果您使用/Zi
而不是/ZI
应该编译代码(但可执行文件不支持编辑并继续)。
[...]
该错误被认为是一项功能...
来自MSVC 文档:
该
/ZI
选项类似于/Zi
,但它生成的 PDB 文件格式支持“编辑并继续”功能。[...] 该/ZI
选项也与__LINE__
预定义宏的使用不兼容;编译的代码/ZI
不能__LINE__
用作非类型模板参数,但__LINE__
可以用于宏扩展。
但是,当我在发布模式下尝试此操作时:它会编译、构建、运行并产生适当的输出:
我想它的原因是/ZI
vs/Zi
标志的差异。你的发布模式标志有/Zi
,所以它编译得很好。
推荐阅读
- unix - OpenBSD VPS 的问题
- google-cloud-platform - 我可以在不保留外部 IP 的情况下将我的 VM 公开吗?
- database - 使用 delphi 和 firebird 的多层 Web 应用程序的架构设计
- if-statement - 谷歌电子表格根据单元格值更改下拉选项
- arrays - 即使在触发时,for循环也不会将JSON元素添加到数组中
- html - 如何根据容器大小明智地选择图像分辨率?
- xslt - 如何根据多个字段过滤xml
- reactjs - 我试图在我的反应组件中使用三元运算符呈现标签,但是当我运行代码时,我的标签被忽略
- java - 有没有办法快速重建和运行 Java 代码,而不是“javac file.java”然后“java 文件”?
- javascript - 如何验证外部javascript文件中的选择下拉值不为空?