我不确定C / C ++三元运算符的执行保证 例如,如果给出一个地址和一个布尔值来告诉该地址是否适合阅读,我可以使用if / else轻松避免错误读取:
int foo(const bool addressGood, const int* ptr) {
if (addressGood) { return ptr[0]; }
else { return 0; }
}
然而,三元运算符(?:
)可以保证除非ptr
为真,否则不会访问addressGood
?或者优化编译器可以生成访问{的代码{1}}在任何情况下(可能导致程序崩溃),将值存储在中间寄存器中并使用条件赋值来实现三元运算符?
ptr
感谢。
答案 0 :(得分:10)
是的,标准保证只有在ptr
为真时才会访问addressGood
。请参阅主题的this answer,引用标准:
条件表达式从右到左分组。第一个表达式在上下文中转换为bool(第4条)。 对其进行评估,如果为真,则条件表达式的结果为第二个表达式的值,否则为第三个表达式的值。 仅评估第二个和第三个表达式中的一个。在与第二个或第三个表达式关联的每个值计算和副作用之前,对与第一个表达式关联的每个值计算和副作用进行排序。
(C ++ 11标准,第5.16 / 1段)
答案 1 :(得分:2)
我想说,除了答案“是的,它是由C ++标准保证的”:
请使用第一张表格。你正在努力实现的目标更加清晰。
我几乎可以保证任何理智的编译器(具有最少量的优化)都会为两个示例生成完全相同的代码。
因此,虽然知道这两种形式实现相同的“保护”是有用的,但绝对优选使用最易读的形式。
这也意味着你不需要写一个评论来解释它是安全的,因为C ++标准中的段落是这样的,因此两者都占用相同数量的代码空间 - 因为如果你没有以前知道它,然后你可以依赖别人也不知道这是安全的,然后花半个小时通过谷歌找到答案,或者遇到这个线程,或者再次提出问题!
答案 2 :(得分:1)
条件(三元)运算符保证仅在第一个操作数比较不等于0时才计算第二个操作数,并且仅在第一个操作数比较等于0时才计算第三个操作数。这意味着您的代码是安全的。
在评估第一个操作数后还有一个序列点。
顺便说一下,你不需要parantheses - addressGood ? ptr[0] : 0
也没关系。
答案 3 :(得分:0)
C ++ 11 / [expr.cond] / 1
条件表达式从右到左分组。第一个表达是 在上下文中转换为bool(第4条)。 它被评估,如果是,则条件表达式的结果是第二个表达式的值, 否则第三个表达。仅评估第二和第三表达式中的一个。每一个价值 计算和与第一个表达式相关的副作用在每个值计算之前被排序 与第二或第三个表达相关的副作用。