想知道下一个语句是否会导致保护错误以及其他可怕的东西,如果next的值为NULL(节点是链表)。
if (!node->next || node->next->some_field != some_value) {
我假设一旦第一部分为真,则不评估OR的第二部分。假设这个我错了吗?这个编译器是否具体?
答案 0 :(得分:10)
在ISO-IEC-9899-1999标准(C99)中,第6.5.14节:
||如果运算符中的任何一个操作数比较不相等,则运算符应为1 到0;否则,它产生0.结果类型为int。 4不同于 按位|运算符,||运营商保证从左到右的评估; 在评估第一个操作数后有一个序列点。 如果第一个操作数比较不等于0,则第二个操作数不是 评价。
这不是特定于编译器的。如果node->next
为NULL
,则剩余的条件为从不评估。
答案 1 :(得分:5)
在OR中,
if ( expr_1 || expr_2)
expr_2仅在expr_1失败(为假)时被“测试”
在AND
中 if( expr_1 && expr_2 )
expr_2仅在expr_1成功(为真)时被“测试”
答案 2 :(得分:2)
可以安全地假设如果左侧的计算结果为true,则不会计算右侧布尔表达式。请参阅relevant question。
答案 3 :(得分:2)
这不是特定于编译器的。您可以放心地依赖短路,您的代码将按预期工作。
答案 4 :(得分:2)
你是对的。
在评估compiler independent
条件(first
之前评估OR
运算符(!node->next
)之前second
始终为node->next->some_field != some_value
条件OR
)first
运算符之后。如果true
条件为expression
,则整个true
仅评估为second
而不评估linked list
条件。
您只是在为next
充分利用此功能。只有在not NULL
时才会进一步访问{{1}}指针。