【问题标题】:MSVC 2019: Order of comma-separated conditions in C++ for-loop changes warningsMSVC 2019:C++ for 循环中逗号分隔条件的顺序更改警告
【发布时间】: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 &lt; N 条件,警告就会消失。如果我交换这两个条件,也没有警告。

我假设!= 运算符有一些被丢弃的返回值,如果它是唯一条件,或者如果它是最后一个条件,它不会被丢弃?这是编译器的预期行为吗??

【问题讨论】:

  • keyIt != keyEnd, j &lt; N 只会返回j &lt; N 的结果。如果你想同时使用这两个条件,你需要keyIt != keyEnd &amp;&amp; j &lt; N
  • 两个逗号分隔的条件 使用逗号运算符将忽略第一个条件(实际评估好然后丢弃),所以它很好编译器正在发出未使用条件的警告。
  • en.cppreference.com/w/cpp/language/operator_other - 阅读关于逗号操作符的部分。
  • 不同之处在于原语j &lt; N之间的内置比较不是nodiscard,因此编译器没有机会警告您。
  • 看起来 VS 2019 正确识别了您代码中的错误,而 VS 2017 无法识别。如果您说不需要keyIt != keyEnd 的结果,则根本不需要测试。但从它的外观来看,它很可能是需要的。所以:keyIt != keyEnd &amp;&amp; j &lt; N

标签: c++ loops warnings visual-c++-2019


【解决方案1】:

谢谢大家! 似乎这个遗留代码的意图确实是&amp;&amp; 这两个条件。逗号运算符是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2011-03-23
    • 2017-12-23
    • 2018-06-01
    相关资源
    最近更新 更多