プログラミング言語C/C++における条件演算子(?:
)と左辺値の扱いについてメモ。言語仕様の隅をつつく話題であり、通常はif文を利用するべき。
下記コードはCでは未定義動作(undefined behavior)を引き起こすが、C++ではwell-definedであり期待通り動作する(変数a
に値42
を代入)。
int a = 0, b = 0, c = 1; (c ? a : b) = 42;
次のようにポインタ経由とすれば、C/C++両方で意図通り動作する。
*(c ? &a : &b) = 42;
C
C99(JTC1/SC22/WG14 N1256) 6.5.15/p4より引用。C11(WG14 N1570)でも同一。
4 The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.95) If an attempt is made to modify the result of a conditional operator or to access it after the next sequence point, the behavior is undefined.
脚注95) A conditional expression does not yield an lvalue.
C++
C++03 5.16/p4より引用。
If the second and third operands are lvalues and have the same type, the result is of that type and is an lvalue.
C++11(JTC1/SC22/WG21 N3337) 5.16/p4より引用。
If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
C.1 CompatibilityにCとC++の差分が明記されている。一部引用。
Change: The result of a conditional expression, an assignment expression, or a comma expression may be an lvalue
Rationale: C++ is an object-oriented language, placing relatively more emphasis on lvalues. For example, functions may return lvalues.
Effect on original feature: Change to semantics of well-defined feature. Some C expressions that implicitly rely on lvalue-to-rvalue conversions will yield different results.
関連URL
- Conditional operator differences between C and C++ - Stack Overflow
- comp.lang.c FAQ list Question 3.16(日本語訳)