C++三元运算符执行条件
C++ ternary operator execution conditions
我不确定C/C++三元运算符的执行保证
例如,如果给我一个地址和一个布尔值,告诉这个地址是否适合阅读,我可以使用if/else:轻松避免糟糕的阅读
int foo(const bool addressGood, const int* ptr) {
if (addressGood) { return ptr[0]; }
else { return 0; }
}
然而,三元运算符(?:
)能否保证除非addressGood
为真,否则不会访问ptr
或者,优化编译器是否可以在任何情况下生成访问ptr
的代码(可能会使程序崩溃),将值存储在中间寄存器中,并使用条件赋值来实现三元运算符?
int foo(const bool addressGood, const int* ptr) {
// Not sure about ptr access conditions here.
return (addressGood) ? ptr[0] : 0;
}
谢谢。
是的,标准保证只有在addressGood
为true时才访问ptr
。请参阅这个主题的答案,其中引用了标准:
条件表达式从右向左分组。第一个表达式在上下文中转换为布尔(第4条)对其求值,如果为true,则条件表达式的结果为第二个表达式的值,否则为第三个表达式的结果只计算第二个和第三个表达式中的一个与第一个表达式相关联的每个值计算和副作用都在与第二个或第三个表达式相关的每个值运算和副作用之前排序。
(C++11标准,第5.16/1段)
我想说,除了"是的,它由C++标准保证"的答案之外:
请使用第一种形式。你想要达到的目标会更加清晰。
我几乎可以保证,任何一个理智的编译器(经过最少的优化)都会为两个例子生成完全相同的代码。
因此,虽然知道这两种形式都能实现相同的"保护"是很有用的,但最好使用最可读的形式。
这也意味着你不需要写一条评论来解释它是安全的,因为C++标准中有这样那样的段落,从而使两者占用了相同的代码空间——因为如果你以前不知道,那么你可以依赖其他人,也不知道这是安全的,然后花半个小时通过谷歌找到答案,要么跑进这个线程,要么再问一次问题!
条件(三元)运算符保证,如果第一个操作数比较不等于0,则仅计算第二个操作数;如果第一个运算数比较等于0,那么仅计算第三个操作数。这意味着您的代码是安全的。
在对第一个操作数求值之后还有一个序列点。
顺便说一句,你不需要偏执狂——addressGood ? ptr[0] : 0
也可以。
c++11/[expr.cond]/1
条件表达式从右向左分组。第一个表达式是上下文转换为布尔(第4条)。它被评估并且如果它为真则条件表达式的结果是第二表达式的值,否则为第三表达式的表达式。只计算第二个表达式和第三个表达式中的一个。每个值在每次值计算之前,对与第一个表达式相关的计算和副作用进行排序以及与第二或第三表达相关的副作用。
- 使用C++中的模板和运算符重载执行矩阵运算
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 运算符 new 的执行顺序和构造函数的参数
- 使用 std::stringbuf 进行缓冲的效果,同时通过插入运算符'<<'执行写入
- 执行运算符在指针上无需取消就可以使用
- C++ - 循环unordered_map - 执行哈希运算符()
- cv::P oint3f 赋值运算符是否执行"深度"复制?
- 当使用三元运算符并删除移动/复制CTOR时,Visual Studio不执行RVO
- 从文件中读取运算符并执行操作C++
- 继承类上的运算符new和delete.操作员删除未执行
- 使用重载运算符在函数调用时执行操作
- C++功能运算符结构不执行任何操作
- 正确执行运算符重载和多态性
- C++:程序的执行(构造函数、析构函数、赋值运算符等)
- 如何重载iostream运算符以在整个流上执行功能
- 由于某种原因,使用 OR 运算符执行操作不起作用
- 要求基类运算符执行"domain check" (C++)
- C++三元运算符执行条件
- 算术运算符执行C++的顺序
- 构造函数和重载运算符执行顺序