C和C++之间的条件运算符差异

rlb*_*ond 46 c c++ conditional-operator

我在某处读到?:C 中的运算符在C++中略有不同,有些源代码在两种语言中都有不同的作用.不幸的是,我找不到任何地方的文字.有谁知道这有什么区别?

gol*_*udo 69

C++中的条件运算符可以返回左值,而C不允许类似的功能.因此,以下内容在C++中是合法的:

(true ? a : b) = 1;
Run Code Online (Sandbox Code Playgroud)

要在C中复制它,您必须求助于if/else,或直接处理引用:

*(true ? &a : &b) = 1;
Run Code Online (Sandbox Code Playgroud)

此外,在C++,?:=运营商有相同的优先级和组从右到左,使得:

(true ? a = 1 : b = 2);
Run Code Online (Sandbox Code Playgroud)

是有效的C++代码,但会在C中抛出错误而在最后一个表达式周围没有括号:

(true ? a = 1 : (b = 2));
Run Code Online (Sandbox Code Playgroud)

  • 在C中你可以写*(true?&a:&b)= 1 (21认同)
  • 第二个区别不是关于操作顺序,而是关于运算符优先级. (5认同)

CB *_*ley 22

主要的实际区别在于,在C中,?:的评估永远不会导致l值,就像在C++中那样.

其定义存在其他差异,几乎没有实际后果.在C++中,第一个操作数转换为bool,在C中将其与0进行比较.这与C和C++之间==,!=等定义的差异是一致的.

在C++中还有更复杂的规则,用于根据第二和第三个操作数的类型推导出一个?:表达式的类型.这反映了在C++中用户定义的隐式转换的可能性.

示例代码.有效的C++; 无效C.

extern int h(int p, int q);

int g(int x)
{
        int a = 3, b = 5;

        (x ? a : b) = 7;

        return h( a, b );
}
Run Code Online (Sandbox Code Playgroud)

gcc 在编译为C时生成错误:"错误:赋值中的无效左值",但编译为C++时代码编译时没有错误.

编辑: 虽然?:不能在C中返回l值,也许令人惊讶的是?:的语法是:

conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression
Run Code Online (Sandbox Code Playgroud)

这意味着即使a ? b : c = d解析(a ? b : c) = d(由于'不是l值'规则),这也不会导致有效的表达式.

C++将语法更改为:

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression
Run Code Online (Sandbox Code Playgroud)

虽然在某些情况下允许条件表达式为l值的扩展可以在a ? b : c = d没有语法更改的情况下生效,但新的语法更改意味着表达式现在有效但具有不同的含义a ? b : (c = d).

虽然我没有任何证据,但我认为由于语法改变不能破坏与现有C代码的兼容性,新语法更有可能产生更少的意外,例如:

make_zero ? z = 0 : z = 1;
Run Code Online (Sandbox Code Playgroud)