关于短路评估的安全问题

ams*_*mso 4 c

可能重复:
是否在C/C++中强制要求短路布尔运算符?和评估顺序?

AFAIK短路评估意味着仅在我们可以保证其结果的点上评估布尔表达式.

这是perl中常见的习惯用法,我们可以编写如下内容:(is_ok()在"OK"上返回非零值)

is_ok() || die "It's not OK!!\n";
Run Code Online (Sandbox Code Playgroud)

代替

if ( ! is_ok() ) {
    die "It's not OK!!\n";
}
Run Code Online (Sandbox Code Playgroud)

这只能起作用,因为评估的顺序始终是从左到右,并且只保证最右边的语句只在第一个语句不是"false"时执行.

在CI中可以做类似的事情:

struct foo {
    int some_flag;
} *ptr = 0;

/* do some work that may change value of ptr */
if ( 0!=ptr && ptr->some_flag ) {
    /* do something */
}
Run Code Online (Sandbox Code Playgroud)

使用这种成语是否安全?

或者,ptr->some_flag在确保ptr不是零指针之前,编译器是否有可能生成评估代码?(我假设如果它是非null,则指向一些有效的内存区域).

这种语法使用起来很方便,因为它可以节省输入而不会失去可读性(我认为无论如何).但是我不确定它是否完全安全,这就是为什么我想了解更多.

注意:如果编译器对此有影响,我使用的是gcc 4.x.

Mat*_*lia 7

短程运算符(||&&)的评估顺序由标准保证从左到右(否则它们将失去部分有用性).

§6.5.134

与按位二元&运算符不同,运算&&符保证从左到右的评估; 在评估第一个操作数后有一个序列点.如果第一个操作数比较等于0,则不计算第二个操作数.

§6.5.144

与按位运算|符不同,运算符||保证从左到右的评估; 在评估第一个操作数后有一个序列点.如果第一个操作数比较不等于0,则不计算第二个操作数.