3

这个问题在我脑海里已经有一段时间了,所以有时间把它说出来,看看你们对此有什么看法。

在 C/C++ 中,运算符优先级由 C 规范定义,但与所有内容一样,编译器可能会以“优化”的名义使用后门或未知/不为人知的东西,最终会弄乱你的应用程序。

举个简单的例子:

bool CheckStringPtr(const char* textData)
{
    return (!textData || textData[0]==(char)0);
}

在这种情况下,我测试指针是否为空,然后检查第一个字符是否为零,本质上这是对零长度字符串的测试。从逻辑上讲,这两个操作是可交换的,但如果在某些情况下发生这种情况,它会崩溃,因为它试图读取一个不存在的内存地址。

所以问题是:是否有任何东西可以强制执行运算符/函数的执行顺序,我知道最安全的方法是使用彼此下方的 2 个 IF,但假设运算符的评估顺序永远不会,这种方式应该是相同的改变。那么 C/C++ 规范是否强制编译器不更改评估顺序,或者有时允许它们更改顺序,比如它取决于编译器参数,尤其是优化?

4

2 回答 2

11

首先请注意,优先级评估顺序是两个不同(基本上不相关)的概念。

那么 C/C++ 规范是否强制编译器不更改评估顺序?

编译器必须产生与 C 语言标准所保证的行为一致的行为。只要整体观察到的行为不变,就可以自由地改变例如评估的顺序。

从逻辑上讲,这两个操作是可交换的,但如果在某些情况下发生这种情况,它就会崩溃

||并被&&定义为具有短路语义;它们不能互换。

于 2013-10-14T20:19:32.763 回答
3

C 和 C++ 标准明确支持短路求值,因此要求 、 或 运算符的左侧操作数&&||右侧?之前进行求值。

其他“序列点”包括逗号运算符(不要与分隔函数参数的逗号混淆,如f(a, b))、语句结尾 ( ;) 以及函数参数的评估和函数调用之间。

但在大多数情况下,评估顺序(不要与优先级混淆)是实现定义的。因此,例如,不要依赖于f在表达式中首先调用f(x) + g(y).

于 2013-10-14T20:32:25.310 回答