当前位置: 首页 > 知识库问答 >
问题:

为什么GCC仅仅通过将未定义的行为放入循环中就被诱骗允许它?

湛鸿雪
2023-03-14
#include <iostream>
#include <string>

int main()
{
  for (int ii = 0; ii < 1; ++ii)
  {
    const std::string& str = str; // !!
    std::cout << str << std::endl;
  }
}
error: ‘str’ is used uninitialized in this function [-Werror=uninitialized]
    null

我已经为此提交了一个GCC bug:https://GCC.gnu.org/bugzilla/show_bug.cgi?id=63203--我仍然希望在这里更好地理解哪里出了问题,以及它如何影响类似诊断的可靠性。

共有1个答案

顾承平
2023-03-14

我仍然想在这里更好地理解哪里出了问题,以及它如何影响类似诊断的可靠性。

与Clang不同,GCC没有检测自初始化引用的逻辑,因此在这里获取警告依赖于检测未初始化变量使用的代码,这是非常复杂和不可靠的(请参阅更好的未初始化警告进行讨论)。

使用int,编译器可以发现您向流中写入了未初始化的int,但是使用std::string,在std::string类型表达式和获取它所包含的const char*之间显然存在太多抽象层,GCC无法检测到该问题。

extern "C" int printf(const char*, ...);

struct string {
  string() : data(99) { }
  int data;
  void print() const { printf("%d\n", data); }
};

int main()
{
  for (int ii = 0; ii < 1; ++ii)
  {
    const string& str = str; // !!
    str.print();
  }
}

d.cc: In function ‘int main()’:
d.cc:6:43: warning: ‘str’ is used uninitialized in this function [-Wuninitialized]
   void print() const { printf("%d\n", data); }
                                           ^
d.cc:13:19: note: ‘str’ was declared here
     const string& str = str; // !!
                   ^
 类似资料:
  • 尽管标题出现了,但这并不是一个哲学问题。 从未初始化的数组读取 使用错误数据 使用不可移植构造。(即内存分配的细节1) 导致具有的行为 标准没有要求产生可预测的效果 我会称之为“未定义的行为”。但也许我错过了什么(?) null null

  • 我想知道,在卷积神经网络中,是否应该对每个像素分别应用批处理归一化,还是应该对每个通道取像素的平均值? 我在Tensorflow的tf描述中看到了这一点。图层。batch\u归一化建议对通道执行bn,但如果我回忆正确,我使用了另一种方法,效果很好。

  • 当我编写以下代码时,我得到了预期的错误

  • 我一直在捕捉非数字时遇到问题。 我试过了,但抓不住。如果我让它捕获非数字,但不让用户再次尝试输入。。。它完全停止了我的代码。 这是我的密码:

  • 问题内容: 我只是发现我认为PLSQL与Oracle中的SQL有点意外的行为。 如果我在SQLDeveloper上运行此查询,则会得到5个结果: 但是,如果我在SQLDeveloper中运行以下语句: 变量 w_counter 以值1(怪异)结束 但最奇怪的部分是,如果我将查询封装在子查询中…… 该 w_counter 变量完成与价值5 … 你对此有什么要说的? 我正在使用Oracle 9.2i

  • 我想只允许特定的组件作为孩子。例如,假设我有一个Menu组件,它应该只包含作为子组件,如下所示: 因此,当我尝试将另一个组件作为子组件时,我希望Typescript在IDE中抛出一个错误。有东西警告我,我应该只作为孩子使用。例如,在这种情况下: 此线程几乎类似,但不包括TypeScript解决方案。我想知道这个问题是否可以使用TypeScript类型和接口来解决。在我想象的世界中,它看起来是这样的