这个问题一直存在我的脑海中,所以有时间让它出来,看看你们有什么话要说。
在C / C ++中,运算符优先级由C规范定义,但与所有内容一样,可能存在后门或未知/未知的事情,编译器可能会以“优化”的名义使用这些内容,这会使您的应用程序陷入困境结束。
举个简单的例子:
bool CheckStringPtr(const char* textData)
{
return (!textData || textData[0]==(char)0);
}
在这种情况下,我测试指针是否为空然后我检查第一个char是零,本质上这是一个零长度字符串的测试。从逻辑上讲,这两个操作是可以交换的,但如果在某些情况下会发生这种情况,那么它会崩溃,因为它试图读取一个不存在的内存地址。
所以问题是:是否有任何强制执行操作符/函数的顺序,我知道最安全的方法是使用彼此之下的2个IF,但这种方式应该是相同的假设运营商的评估顺序永远不会改变。 因此,C / C ++规范强制要求的编译器不会改变评估顺序,或者有时它们是否允许更改顺序,例如它取决于编译器参数,尤其是优化?
答案 0 :(得分:11)
首先请注意,优先级和评估顺序是两个不同的(很大程度上不相关的)概念。
C / C ++规范强制要求编译器不改变评估顺序吗?
编译器必须生成与C语言标准保证的行为一致的行为。它可以自由改变,例如评估的顺序,只要整体观察到的行为不变。
逻辑上,这2个操作是可交换的,但如果在某些情况下会发生这种情况,那么它就会崩溃
||
和&&
被定义为具有short-circuit语义;他们可能不会互换。
答案 1 :(得分:3)
C和C ++标准明确支持短路评估,因此需要在右侧之前评估&&
,||
或?
运算符的左侧操作数 - 手边。
其他“序列点”包括逗号运算符(不要与在f(a, b)
中分隔函数参数的逗号混淆),语句结束(;
),以及在函数的参数和对函数的调用。
但是在大多数情况下,评估顺序(不要与优先级混淆)是实现定义的。因此,例如,不要依赖f
在f(x) + g(y)
等表达式中首先调用。