是否存在C4172 Visual C++;警告不应被视为错误? 对于函数返回本地或临时地址或引用局部变量的情况,有VisualC++警告。

是否存在C4172 Visual C++;警告不应被视为错误? 对于函数返回本地或临时地址或引用局部变量的情况,有VisualC++警告。,c++,visual-c++,compiler-warnings,C++,Visual C++,Compiler Warnings,大概是这样的: int& fun() { int var; return var; //C4172 } 现在看来,使用 > PraceMaultActudio使VisualC++将C4172当作错误并中断编译是不错的主意。 是否存在C4172实际上不是错误的合理情况?我不知道为什么会有人想这样做: int * stackTester() { int dummy; return &dummy; } bool stackGoesUp() {

大概是这样的:

int& fun()
{
    int var;
    return var; //C4172
}

现在看来,使用 > PraceMaultActudio使VisualC++将C4172当作错误并中断编译是不错的主意。


是否存在C4172实际上不是错误的合理情况?

我不知道为什么会有人想这样做:

int * stackTester()
{
    int dummy;
    return &dummy;
}

bool stackGoesUp()
{
    int dummy;
    return stackTester() > &dummy;
}

但一般来说,您应该将警告视为错误。

这是一个1级警告,很难忽略。但是编译器遵循这里的语言标准,调用UB是不被禁止的。这是一个非常常见的bug,它经常会有好的结局。只要不进行任何函数调用,指向堆栈的位置就保持稳定

处理这一问题的最佳方法是始终将警告转化为错误。使用IDE中的/WX“将警告视为错误”设置编译。如果您随后有意要抑制警告,则“pragma warning”会向所有人清楚地表明,发生了一些可疑的事情,这是经过深思熟虑的,而不是意外事件。

未使用的代码

class base
{
   virtual blah& makeBlah() 
}

class red : public base
{
    blah& makeBlah() { return blah(); } // there are no red blahs, never called
}

class blue : public base
{
    blah& makeBlah() { actual code to make a blah }
}

因此,您想知道是否可以将其永久性地视为一个错误——意思是:为什么从一开始就将其定义为一个警告?很好的问题。很可能不是,编译器将其作为诊断而不是编译错误提供是正确的,因为返回对本地的引用而不是语言语法错误是未定义的行为。为什么没有定义为语言语法错误?因为它不是语法错误。@Alok如果是UB,编译器有权将其视为错误。@Alok,但这不是问题所在。(此外,你反复提到的“语法”是一种转移注意力的手段,还有其他类型的错误必须诊断。)@Alok,但这也不是问题所在。问题是,无论标准是否允许代码,从用户角度来看,始终将此警告视为错误是否有意义。这是完全不同的。一个稍微理智一点的例子:如果我理解C标准,找出最小堆栈帧有多大(=返回地址的大小?),将指针与>、=和@AlexeyFrunze:True进行比较,但是为指针定义了
std::less
,即使它们不指向同一数组的元素。