gpt4 book ai didi

c++ - gcc:混合 __builtin_expect 和 noreturn

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:42:50 25 4
gpt4 key购买 nike

在我正在处理的一个大项目中,我们倾向于在我们的错误检查中使用 gcc 的 __builtin_expect(通常是在该错误将要中止当前操作时):

if( __builtin_expect( failed, 0 ) )
// handle error and fail

另一方面,我们有一组(小的)集中式错误函数来处理某些错误类型(即:消费者用完了数据)。

这些函数都以抛出异常结束,因此它们永远不会返回。

这使我们的错误检查成为:

if( __builtin_expect( got_bytes, 0 ) )
customError( NoDataErrorCode, "No more data" ) ; // <-- always throws an exception

为了避免出现一些警告,我决定将这些函数标记为 noreturn。

通过阅读 gcc 的 __builtin_expect 和 noreturn 文档,我明白这应该没有问题,但你永远不知道。

我写了一个小测试程序:

#include <stdexcept>

void throwIt( void ) __attribute__( ( noreturn ) ) ;

void throwIt( bool )
{
throw std::runtime_error( "forced error" ) ;
}

void iffail( bool failed )
{
if( __builtin_expect( failed, 0 ) )
throwIt( failed ) ;
}

int main( int argc, char ** )
{
iffail( !!( argc & 1 ) ) ;

return 0 ;
}

用 -O3 -S 编译它并检查汇编代码我发现在这个特殊情况下内置函数和属性都是无关紧要的。删除其中任何一个(或两个)都会产生完全相同的汇编代码。这让我想知道 __builtin_expect 是否对其中包含简单函数调用的简单 if 语句有任何影响。

注意:throwIt 的 bool 参数用于强制编译器做一些事情,而不仅仅是在 if 中调用函数。

所以我的问题是:这种安排是否安全,或者是否会出现反作用。

最佳答案

是的,它是安全的。如下所述,它可能会或可能不会对实际代码产生影响。

__attribute__(noreturn) 和 __builtin_expect 的目的是帮助编译器。

如果您执行以下操作,noreturn 属性会避免出现“没有返回语句的函数返回”的警告:

void panic(const char *msg) __atrribute__(noreturn);

int func(int x)
{

if (x < 0)
panic("x must not be negative");
else
return x * 42;
}

(当然,在这种特殊情况下,else 是完全多余的 - 但我相信我们可以想出一个例子,其中发生了这种事情并且返回不存在)

expect“函数”帮助编译器理解“这很可能发生”或“这不太可能发生”,编译器将根据是否可能发生来选择“最佳路径”,例如:

if (failed)
throwIt( failed );

现在,如果编译器认为有可能失败,它会生成如下代码:

if (!failed) goto not_failed;

throwIt( failed );

not_failed:
do_other_stuff();

好像编译器认为失败不太可能是真的:

if (failed) goto do_failed;

do_other_stuff();
return;

do_failed:
throwIt( failed );

(许多处理器也有位告诉分支预测单元用“这被预测为真”或“这被预测为假”来“启动”,这也可能被编码到代码中,并且第二种情况,如果你使用 __builtin_expect)。

当然,在您的情况下,编译器很可能会“猜测”内联抛出是一种没有提示的不太可能的情况,因此无论哪种方式都会生成相同的代码段。或者它只是“巧合”地产生了这样的代码。

此外,不同的处理器以及 gcc 的目标后端或多或少复杂,因此根据具体针对哪个目标进行编译,某些处理器与其他处理器之间的差异可能会有很大差异。

关于c++ - gcc:混合 __builtin_expect 和 noreturn,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26023977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com