2011-05-27 24 views
12

Mira el siguiente código:¿Por qué se permite un literal wchar_t vacío?

int main(int argc, char* argv[]) 
{ 
    // This works: (Disable Lang Ext = *Yes* (/Za)) 
    wchar_t wc0 = L'\0'; 
    wchar_t wc_ = L''; 
    assert(wc0 == wc_); 

    // This doesn't compile (VC++ 2010): 
    char c0 = '\0'; 
    char c_ = ''; // error C2137: empty character constant 
    assert(c0 == c_); 
    return 0; 
} 

¿Por qué el compilador permiten definir un vacío carácter literal de caracteres anchos? Esto no tiene sentido para wide, al igual que no tiene sentido para char donde el compilador señala un error.

¿Esto está permitido por la norma?

+0

gcc 4.6.0 rechaza ambas declaraciones. – pmr

Respuesta

11

Esto es a bug in VC++.

+0

De hecho. Y [no parece que va a arreglarse] (https://connect.microsoft.com/VisualStudio/feedback/details/250372/vc-allows-empty-wide-characters-but-not-empty- caracteres) –

+3

Me pregunto si VC++ 2023 tendrá este error ... –

+0

¡Guau! Pasé un par de horas en vano debido a esto (estoy en VS2010). Fue un error suponer que agregar L '' no haría ningún cambio en la cadena. –

3

Yo diría que el primer ejemplo no se permite, por 2.23.2.1 de la norma C++:

un carácter literal es uno o más caracteres encerrados entre comillas simples, como en ’x’ , opcionalmente precedido por la letra L, como en L’x’.

(Énfasis mío.)

4

Es no permitido por la norma ISO. Esto es un error en el producto de Microsoft. Incluso su page describing that particular feature no menciona este comportamiento aberrante (o aborrecible, según su punto de vista).

La definición de un carácter literal (tomadas de 2.14.3 de C++ 0x pero el bit en cuestión no ha cambiado desde C++ 03) contiene:

character-literal: 
    L’ c-char-sequence ’ 
c-char-sequence: 
    c-char 
    c-char-sequence c-char 
c-char: 
    any member of the source character set except 
     the single-quote ’, backslash \, or new-line character 
    escape-sequence 
    universal-character-name 
escape-sequence: 
    simple-escape-sequence 
    octal-escape-sequence 
    hexadecimal-escape-sequence 
simple-escape-sequence: one of 
    \’ \" \? \\ \a \b \f \n \r \t \v 
octal-escape-sequence: 
    \ octal-digit 
    \ octal-digit octal-digit 
    \ octal-digit octal-digit octal-digit 
hexadecimal-escape-sequence: 
    \x hexadecimal-digit 
    hexadecimal-escape-sequence hexadecimal-digit 

Como se puede ver, no hay ninguna manera en que puede terminar sin nada entre los caracteres ' en L'x'. Tiene que ser uno o más de los caracteres c_char. De hecho, esto se hace explícito en el párrafo siguiente (el subrayado es mío):

Un carácter literal es uno o más caracteres entre comillas simples, como en ’x’, opcionalmente precedido por una de las letras u, U, o L, como en u’y’, U’z’ o L’x’, respectivamente.

Cuestiones relacionadas