Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否存在审计人员无法诊断缺失申报的情况?_C++_Return_Compiler Warnings - Fatal编程技术网

C++ 是否存在审计人员无法诊断缺失申报的情况?

C++ 是否存在审计人员无法诊断缺失申报的情况?,c++,return,compiler-warnings,C++,Return,Compiler Warnings,我做了一些研究,以找出为什么丢失的报税表不能是错误,而是未定义的行为。我发现它使用以下示例来说明为什么它不可能是错误: 模板 调用(std::函数f){ 如果(f) 返回f(); 其他的 中止程序(); //无法在此处写入返回,因为我们无法创建t值 } 请注意,此示例是完全有效的代码。它在所有分支上都没有回报,但仍然没有UB。这就解释了为什么不在所有分支上返回是错误的,而不是错误的。该示例可以“修复”为声明abort_program()作为[[noreturn]]使其不再是一个反参数。我怀疑编

我做了一些研究,以找出为什么丢失的报税表不能是错误,而是未定义的行为。我发现它使用以下示例来说明为什么它不可能是错误:

模板
调用(std::函数f){
如果(f)
返回f();
其他的
中止程序();
//无法在此处写入返回,因为我们无法创建t值
}
请注意,此示例是完全有效的代码。它在所有分支上都没有回报,但仍然没有UB。这就解释了为什么不在所有分支上返回是错误的,而不是错误的。该示例可以“修复”为声明
abort_program()
作为
[[noreturn]]
使其不再是一个反参数。我怀疑编译器在正确诊断这个示例时会遇到问题。如果缺少返回值会变成错误,则规则可能需要更改一点,因为只有使用
[[noreturn]]
才能正确诊断上述示例

然而,我要寻找的是一个不同的例子,编译器无法检测到丢失的返回。该评论还提到存在编译器无法诊断的情况,但我没有找到这样的示例

如果警告是可靠的(上面的假阳性除外),为了安全起见,我可以将警告视为错误

是否确实存在编译器无法检测到丢失返回的情况?这只是病理代码,还是每天都会发生?我能相信这个警告吗


为了让它有责任感,让我们专注于gcc(最新版本):在什么情况下,gcc没有警告丢失的返回?

很难证明某些东西不存在,但是,很难找到一个示例足以令人信服地看到,只有病态代码才会导致编译器不警告丢失的返回

首先,我的思路是按照以下思路构建一个复杂的示例:

int fun() {
    goto exit;
    return 1;
    exit: ;      
}
然而,无论我如何努力,gcc都会对此类代码发出警告。我想得越多,我就越确信问题不在于编译器不会发出警告的代码,而在于错误的提示。如果问题中的示例更改为

   template<typename T>
   T maybe_call(std::function<T(void)> f) {
           if (f)
                   return f();
           else
                   maybe_abort_program();

           // Cannot write a return here, because we have no way to create a value of t
   }
模板
调用(std::函数f){
如果(f)
返回f();
其他的
可能会中止程序();
//无法在此处写入返回,因为我们无法创建t值
}
然后由编译器来决定
是否可能\u abort\u program
最终返回,这是一个在所有情况下都无法确定的停止问题。更改函数名当然不会改变任何东西,但这只是为了强调,即使函数可以标记为
[[noreturn]]]
,但如果不这样标记,代码仍然可以有效(或无效),编译器也无法可靠地诊断它


但是,编译器可以对此类情况发出警告。经过一段时间的实验,我没有发现任何编译器没有发出警告的例子。因此,我的结论是:我可以(在某种程度上)相信这个警告

没有理由存在这种情况

在定义良好的程序中,函数中的每个代码路径应仅包含数据操作(不能终止函数的执行)、内部流(循环等,这些循环根据定义在函数中是自包含的),
return
语句结束函数,并
throw
s/
longjmp
s/
exit
s/
abort
s结束函数。这些对编译器来说都是微不足道的

除此之外,它只是函数调用,递归地应用于函数调用


您在这里提到的示例/错误实际上是相反的:由于您没有编写
返回
,并且您依赖调用的函数执行
抛出
/
长jmp
/
退出
/
中止
,而编译器可能不知道这一点,因此得到警告,如果被调用的函数不执行该操作,那么您的函数将具有未定义的行为……并且您没有使用编译器内在信号表示代码路径“不可访问”。通常我更喜欢内在的,而不是关闭
-Werror
;它甚至可以为您提供性能优势堕胎程序函数被标记为“代码> NordeURN < /Calp>(使用编译器特定属性或C++标准属性),编译器就可以处理它。否则,对于可选的返回值,可以使用(或).Script程序员,好点,但也没有<代码> [NoReURN]该示例是有效的代码。关于你的第二条评论:问题不在于我所包含的示例,而是关于一个缺少返回但没有触发警告的示例。我相信gcc没有问题警告这个例子。抱歉,如果这不是很清楚,警告是一个有效的诊断,这是必需的。@Swift FridayPie不确定我是否理解你的评论。Afaik缺少返回是未定义的行为,不需要诊断。
goto
示例并不复杂,只是
而(true){return 1;}
。可由编译器进行简单的检查,确保这一点的规则是相同的,这意味着任何
goto
链卷积到足以“破坏”编译器中的代码路径分析,这是该语言的法律不允许的。@swithwings我没有写过,这段代码是卷积的。我写道,我试图沿着我所包含的代码行,提出一个复杂的代码。我也知道,<代码> Goto 不会立即中断C++,但我希望使用<代码> Goto < /Cord>来获得我要查找的示例。
   template<typename T>
   T maybe_call(std::function<T(void)> f) {
           if (f)
                   return f();
           else
                   maybe_abort_program();

           // Cannot write a return here, because we have no way to create a value of t
   }