去年から気になっていることがある。条件演算子の結果の型だ。
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が間違っている。
"one of the following shall hold" として挙げられている条件に
ReplyDelete合わないのだから、コンパイルエラーになるのが正しいのだと解釈できる
ように思います。
手元の 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'
なるほど、そういう解釈もあったか。
ReplyDelete