返回的局部变量引用:为什么要警告?为什么不出错?

时间:2014-10-15 02:28:48

标签: c++ warnings undefined-behavior

考虑代码:

int& getValue()
{
  int i = 10;
  return i;
}

这会导致编译器警告:

  

警告:引用局部变量`i'返回

我理解警告的原因。我将返回对局部变量的引用,该变量在我超出范围时就会被销毁。

我的问题是:为什么这甚至被允许?为什么编译器不会简单地给出错误而不是警告?

2 个答案:

答案 0 :(得分:5)

undefined behavior编译器甚至没有义务提供诊断,更不用说使它成为错误。 1.4 实施合规性部分中的draft C++ standard说:

  

可诊断规则集包含所有语法和语义   本国际标准中的规则除了包含的规则   一个明确的符号“不需要诊断”或哪些是   被描述为导致“未定义的行为”。

这主要是因为编译器确定何时存在未定义的行为并且迫使编译器检测所有情况并不总是微不足道的事情将被视为过度负担。

尽管现代编译器非常擅长捕获各种不良行为,包括未定义的行为,gccclang我发现以下一组标志很有用:-Wall -Wextra -Wconversion -pedantic。< / p>

您可以将这些错误转换为可以使用-Werror的错误,我强烈推荐。它迫使你理解为什么每个警告都会产生,并且有纪律可以找到更好的解决方案,从长远来看,这将为你节省很多痛苦。

请注意,我们可能会将 constexpr 函数的结果分配给 constexpr 变量,因为我们可能会因可检测的未定义行为而强制出错。 {3}}

以下C ++ 14代码:

constexpr int& getValue()
{
  int i = 10;
  return i;
}

int main()
{
    constexpr int &p = getValue();
    //...
}

使用clang生成以下错误:

error: constexpr variable 'p' must be initialized by a constant expression
    constexpr int &p = getValue();
                   ^   ~~~~~~~~~~

答案 1 :(得分:1)

这是因为你要求编译器编译的是编译器。从广义上讲,错误应该表明你的代码无法被理解;警告只是表明你可能犯了一个错误(在这种情况下:触发未定义的行为)。