setjmp和GCC的合法用法

使用GCC(4.0 for me),这是合法的:
if(__builtin_expect(setjmp(buf) != 0, 1))
  {
    // handle error
  }
else
  {
    // do action
  }
我发现一个讨论说它在2003年给GCC造成了问题,但我想他们现在已经修好了。 C标准说使用
setjmp
是违法的,除非它是四个条件之一,相关的是这个:      关系或等于运算符的一个操作数与另一个操作数的整数常量表达式,结果表达式是选择或迭代语句的整个控制表达式;    但如果这是GCC扩展,我可以保证它可以用于GCC,因为它已经是非标准功能吗?我测试了它似乎工作,但我不知道我必须做多少测试来实际打破它。 (我隐藏了一个宏后面的
__builtin_expect
的调用,这被定义为非GCC的无操作,所以对其他编译器来说这是完全合法的。)     
已邀请:
但如果这是GCC扩展,我可以保证它可以用于GCC,因为它已经是非标准功能吗?我测试了它似乎工作,但我不知道我必须做多少测试来实际打破它。 (我隐藏了对宏后面的__builtin_expect的调用,这被定义为非GCC的无操作,所以对于其他编译器来说这是完全合法的。) 你是对的,__ builtin_expect应该是其他编译器的宏无操作,所以结果仍然是定义的。     
我认为标准所讨论的是要做到这样的事情:
int x = printf("howdy");
if (setjmp(buf) != x ) {
    function_that_might_call_longjmp_with_x(buf, x);
} else {
    do_something_about_them_errors();
}
在这种情况下,您不能再依赖于具有在上一行中分配的值的
x
。编译器可能已移动了
x
所在的位置(重新使用它所在的寄存器或其他内容),因此进行比较的代码将查找错误的位置。 (你可以将
x
保存到另一个变量,然后在调用函数之前将
x
重新分配给其他东西,这可能会使问题更加明显) 在您的代码中,您可以将其写为:
int conditional;
conditional = setjump(buf) != 0 ;
if(__builtin_expect( conditional, 1)) {
    // handle error
} else {
    // do action
}
而且我认为我们可以满足自己,分配变量
conditional
的代码行满足了这个要求。     

要回复问题请先登录注册