最近的 Visual Studio Studio 升级到版本 15.6.2 包括一个 Visual C++ 编译器更新,该更新导致以下代码在该push_back
行出现警告,原因是[[nodiscard]]
:
#include <vector>
struct [[nodiscard]] S
{
int i;
};
int main()
{
std::vector<S> v;
v.push_back({ 1 }); // causes warning C4834
}
像这样调用编译器(请注意,无需指定高警告级别即可重现,但这/std:c++latest
是必需的,并且/permissive-
是可选的):
cl /nologo /EHsc /permissive- /std:c++latest test.cpp
警告来自 Visual C++ 自己的std::vector
-implementation 代码并说:
warning C4834: discarding return value of function with 'nodiscard' attribute
(完整的警告输出见下文)
编译器版本:
Microsoft (R) C/C++ Optimizing Compiler Version 19.13.26128 for x64
我的理论是这个警告是由以下原因引起的:
- Visual C++ 实现
push_back
方面emplace_back
, emplace_back
在 C++17 中返回一个引用,并且_HAS_CXX17
如果设置了宏,那么在 Visual C++ 中后一个函数的实现有点奇怪(对我来说) 。
但是,不管任何内部库代码如何,Visual C++ 在生成这些诊断消息时是否违反了标准?wandbox.org 上最新的 Clang 和 GCC 版本不会对相同的代码产生任何警告。
nodiscard
我坚持认为用户类型的库内部用法S
永远不会引起警告,因为这会使该功能在实践中无法使用,但nodiscard
§10.6.7/2 [dcl.attr.nodiscard] 中的简短描述有点含糊那个话题。
还是该标准只是简单地“阻止”此类警告,而这确实是一个 QoI 问题,尽管在这种情况下是一个相当严重的问题,但严重到应该将其作为错误报告提交给 Microsoft?
这是完整的警告:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include\vector(996): warning C4834: discarding return value of function with 'nodiscard' attribute
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include\vector(995): note: while compiling class template member function 'void std::vector<S,std::allocator<_Ty>>::push_back(_Ty &&)'
with
[
_Ty=S
]
test.cpp(11): note: see reference to function template instantiation 'void std::vector<S,std::allocator<_Ty>>::push_back(_Ty &&)' being compiled
with
[
_Ty=S
]
test.cpp(10): note: see reference to class template instantiation 'std::vector<S,std::allocator<_Ty>>' being compiled
with
[
_Ty=S
]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include\vector(1934): warning C4834: discarding return value of function with 'nodiscard' attribute
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include\vector(1933): note: while compiling class template member function 'void std::vector<S,std::allocator<_Ty>>::_Umove_if_noexcept1(S *,S *,S *,std::true_type)'
with
[
_Ty=S
]
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\include\vector(1944): note: see reference to function template instantiation 'void std::vector<S,std::allocator<_Ty>>::_Umove_if_noexcept1(S *,S *,S *,std::true_type)' being compiled
with
[
_Ty=S
]