2010-02-04

条件演算子が分からん

去年から気になっていることがある。条件演算子の結果の型だ。

If either the second or the third operand has type (possibly cv-qualified) void, then the lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the second and third operands, and one of the following shall hold:

— The second or the third operand (but not both) is a throw-expression (15.1); the result is of the type of the other and is an rvalue.

— Both the second and the third operands have type void; the result is of type void and is an rvalue. [ Note: this includes the case where both operands are throw-expressions. —end note ]

以下のような場合は、この説明では、漏れるのではないか。

void f() ;

int main()
{
    // 片方がvoidで、もう片方が非void
    true ? 0 : f() ;
}

どちらもthrow式ではない。しかも、片方しか、voidではない。規格は、この場合を書き漏らしているように読めるのだが。

ちなみに、手元のVC10 Beta2で試したところ、結果の型はvoidであった。

追記:one of the following shall holdなので、どちらの条件にも一致しない場合、ill-formedである。MSVCが間違っている。

2 comments:

Anonymous said...

"one of the following shall hold" として挙げられている条件に
合わないのだから、コンパイルエラーになるのが正しいのだと解釈できる
ように思います。
手元の gcc 4.3.4 では、この解釈に従ったと思われるエラーが発生します。
> 6: error: third operand to the conditional operator is of type 'void', but the second operand is neither a throw-expression nor of type 'void'

江添亮 said...

なるほど、そういう解釈もあったか。