【发布时间】:2020-09-02 14:27:50
【问题描述】:
将以下代码从 VS2017 移植到 2019 会弹出一个新警告(这是原版的简化版本)。
main.cpp(18,90): 警告 C4834: 丢弃函数的返回值 带有“nodiscard”属性
#include <map>
#include <vector>
using namespace std;
typedef map<int, vector<vector<void*> > > MyMap;
const int N = 16;
int main()
{
MyMap myMap;
for (auto mapIt = myMap.begin(), mapEnd = myMap.end(); mapIt != mapEnd; mapIt++)
{
int j = 0;
for (auto keyIt = (*mapIt).second.begin(), keyEnd = (*mapIt).second.end(); keyIt != keyEnd, j < N; keyIt++, j++)
{
for (auto vecIt = (*keyIt).begin(), vecEnd = (*keyIt).end(); vecIt != vecEnd; vecIt++)
{
if (*vecIt)
{
}
}
}
}
return 0;
}
注意 for 循环有两个逗号分隔的初始化程序、两个逗号分隔的条件等。如果我从 for 循环中删除 j < N 条件,警告就会消失。如果我交换这两个条件,也没有警告。
我假设!= 运算符有一些被丢弃的返回值,如果它是唯一条件,或者如果它是最后一个条件,它不会被丢弃?这是编译器的预期行为吗??
【问题讨论】:
-
keyIt != keyEnd, j < N只会返回j < N的结果。如果你想同时使用这两个条件,你需要keyIt != keyEnd && j < N -
两个逗号分隔的条件 使用逗号运算符将忽略第一个条件(实际评估好然后丢弃),所以它很好编译器正在发出未使用条件的警告。
-
en.cppreference.com/w/cpp/language/operator_other - 阅读关于逗号操作符的部分。
-
不同之处在于原语
j < N之间的内置比较不是nodiscard,因此编译器没有机会警告您。 -
看起来 VS 2019 正确识别了您代码中的错误,而 VS 2017 无法识别。如果您说不需要
keyIt != keyEnd的结果,则根本不需要测试。但从它的外观来看,它很可能是需要的。所以:keyIt != keyEnd && j < N
标签: c++ loops warnings visual-c++-2019