【问题标题】:Compiler warning at std::vector push_back of an int with warning level 3警告级别为 3 的 int 的 std::vector push_back 处的编译器警告
【发布时间】:2023-03-14 01:50:02
【问题描述】:

我使用的是英特尔 c++ 编译器 icc 版本 18.0.3。

如果我用-w3 编译following code

#include <vector>

int main() {
    std::vector<int> vec;
    vec.push_back(2);
    return 0;
}

test_w3.cpp(6): 备注 #383: 复制到临时的值,参考 临时使用 vec.push_back(2);

Replacing2 带有一个 const 变量作为

#include <vector>
int main() {
    std::vector<int> vec;
    const int a = 2;
    vec.push_back(a);
    return 0;
}

不给出警告。

这个警告是什么意思?可以安全地忽略它吗(尽管需要无警告代码)?

【问题讨论】:

  • 如果vector在main函数之外声明或者打印结果,是否给出相同的注释?
  • 如果我打印它,仍然会给出注释。 gcc.godbolt.org/z/atlYe6
  • 根据这篇文章intel-c-compiler/topic/300453。这句话并不重要,从它的声音来看,应该删除它,它可能是一个错误。
  • 如果我转到一个函数,仍然会给出注释。 gcc.godbolt.org/z/fKoED3
  • 这看起来真的像一个错误的警告。如果将 -w3 替换为 -Wall,即使 icc 也不会抱怨相同的代码

标签: c++ vector compiler-warnings


【解决方案1】:

英特尔有一个专门针对此问题的站点,其中正是您的问题here。它是从 2008 年开始的,但似乎适用于您的问题。 警告存在,因为这种编程风格可能会导致隐藏临时对象,在某些情况下可以忽略

他们对这个例子说:

void foo(const int &var)
{
}

void foobar()
{
    std::vector<std::string> numlist
        // 383 remark here: a tempory object with "123" is created
        numlist.push_back("123");       
    foo(10);       // gives 383

}

以下内容:

分辨率:

  • 为初始化引用提供适当的对象。
  • 可以安全地忽略向量的推回功能的此警告。向量将参数复制到自己的存储中;它从不存储原始参数。因此,使用临时的是绝对安全的。

因此您可以忽略警告,即使这与一般规则永远不要忽略警告相矛盾。

在我看来,英特尔选择了一个糟糕的方法,因为误诊导致的警告会阻碍开发。

【讨论】:

  • 不幸的是,忽略警告是一个非常糟糕的主意,因为这意味着真实警告将淹没在误报噪音中。这就是为什么这样的警告(可能是误报)一开始是个坏主意。这是一个不好的警告。它应该在命令行选项中全局禁用。
  • 我完全同意
  • @KonradRudolph 添加了关于忽略警告的警告!谢谢你的建议!
  • 实际上不应该在这里使用emplace_back()吗? ICC 不应该对此发出警告(我不知道它是否,但它不应该)。我的 PoV 仅使用 push 方法来复制/移动现有实例(即不是临时的),但如果从 ctor args 创建新元素,它们应该由 emplace 转发,而不是使用临时作为载体.对我来说,这两个州的意图更清楚,可以避免浪费的复制/移动 - 而且,我今天了解到,警告!
  • @underscore_d push_back 和 emplace_back 都不应该发出警告,但它们会发出警告(gcc.godbolt.org/z/1BDtLX 以 emplace_back 为例)。
猜你喜欢
  • 2022-06-10
  • 2023-03-03
  • 2010-09-28
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
相关资源
最近更新 更多