是否有合规者无法诊断漏报的情况?

问题描述 投票:3回答:1

我进行了一些研究,以了解为什么遗漏的回报不能是错误,而是未定义的行为。我发现this comment in a bug report使用以下示例说明了为什么它不能成为错误:

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

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

请注意,此示例是完全有效的代码。它在所有分支上都没有回报,但是仍然没有UB。这就解释了为什么所有分支都没有回报是UB,不是错误。该示例可以是“固定的”,以将abort_program();声明为[[noreturn]],以减少其计数器参数。我怀疑编译器在正确诊断此示例时会遇到问题。如果缺少返回将变成错误,则规则可能必须稍作更改,因为只有使用[[noreturn]]才能正确诊断上述示例。

但是,我要寻找的是另一个示例,其中编译器无法检测到缺少的返回值。该评论还提到存在编译器无法诊断的情况,但是我找不到这样的示例。

如果警告是可靠的(如上述错误肯定,我可以将警告视为错误,是出于安全考虑。

确实在某些情况下编译器无法检测到缺少的收益吗?是仅在病理代码中发生,还是在每天的代码中发生?我可以依靠警告吗?

为了使其易于回答,让我们专注于gcc(最新版本):在什么情况下gcc无法警告缺少收益?

c++ return compiler-warnings
1个回答
0
投票

很难证明某物不存在,但是很难找到一个例子就足以令人信服,以至于只有病理代码会导致编译器不警告缺少返回值。

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

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
   }

然后,由编译器决定maybe_abort_program是否最终返回,这是无法在所有情况下都确定的暂停问题。更改函数的名称当然不会改变任何东西,但是只是强调即使认为函数could都标记为[[noreturn]],而不是将其标记为这样,代码仍然有效(或无效),并且编译器无法可靠地诊断出来。

但是,编译器可以警告这种情况。经过一番试验后,我没有找到编译器未发出警告的任何示例。因此,我的结论是:我可以(在某种程度上)依靠警告。

© www.soinside.com 2019 - 2024. All rights reserved.