2009-12-23

VC10 Beta2 のstatic_assertの規格違反

N3000によれば、static_assertは、以下のように定義されている。

static_assert ( constant-expression , string-literal ) ;

string-literalは、以下のように定義されている。

2.14.5 String literals [lex.string]
string-literal:
    encoding-prefix opt " s-char-sequenceopt "
    encoding-prefix opt R raw-string

encoding-prefix:
    u8
    u
    U
    L

とすれば、以下のコードはコンパイルが通るはずである。

int main()
{
    static_assert( true, "..." ) ;
    static_assert( true, R"***[...]***" ) ;
    static_assert( true, u8"..." ) ;
    static_assert( true, u8R"***[...]***" ) ;
    static_assert( true, u"..." ) ;
    static_assert( true, uR"***[...]***" ) ;
    static_assert( true, U"..." ) ;
    static_assert( true, UR"***[...]***" ) ;
    static_assert( true, L"..." ) ; // これだけは最低でもコンパイル出来るべき
    static_assert( true, LR"***[...]***" ) ;
}

しかるに、VC10 Beta 2では、最初のstatic_assert以外、すべてエラーになってしまう。もちろん、VC10は、raw string literalをサポートしていないし、encoding-prefixも、Lしかサポートしていない。しかし、最低でも、L"..."はコンパイルできてしかるべきだ。それが、何故かできない。

これは明らかに規格違反であるが、実は、ここでエンコーディングプレフィクスが使えても、特に役には立たないのである。というのも、規格では、basic source character set外の文字は、メッセージとして表示することを求められていないからだ。

int main()
{
    // OK. でも日本語が表示されるとは限らない
    static_assert( false, U"でっきるかな? できるかな? さてさてホホゥ!" ) ;
}

規格では、このコードは、コンパイルエラーにならなければならない。その際に、diagnostic messageを表示することが、規格では求められているが、basic source character set外の文字は、表示しなくてもよい。というわけで、このコードは、規格準拠のコンパイラであれば、「動く」が、メッセージとして日本語が表示される保証はないのである。

No comments: