sprintf - C99 formateadores de printf vs C++ 11 literales definidos por el usuario
sintaxis de printf y scanf (1)
gcc 4.7.1 es correcto Según la norma,
c ++ 11
2.2 Fases de la traducción [lex.phases]
1 - La precedencia entre las reglas de sintaxis de traducción se especifica en las siguientes fases. [...]
3. El archivo de origen se descompone en tokens de preprocesamiento (2.5) y secuencias de caracteres de espacios en blanco (incluidos los comentarios). [...]
4. Las directivas de preprocesamiento se ejecutan, las invocaciones de macros se expanden, [...]
Y por 2.5 tokens de preprocesamiento [lex.pptoken] , user- de- fi ned-string-literal es una producción de token de preprocesamiento:
2.14.8 literales definidos por el usuario [lex.ext]
literal de cadena de fi nida por el usuario :
cadena-literal ud-sufijo
ud-sufijo :
identificador
Por lo tanto, la expansión de macro de fase 4 de PRId64
es irrelevante, porque el "%"PRId64
ya se ha analizado como un token de preprocesamiento literal de cadena definida por el usuario único que consta de la cadena literal "%"
y PRId64
sufijo PRId64
.
Oh, esto va a ser increíble ; todos tendrán que cambiar
printf("%"PRId64"/n", val);
a
printf("%" PRId64"/n", val); // note extra space
¡Sin embargo! gcc y clang han acordado tratar los literales de cadena definidos por el usuario sin un subrayado principal en el sufijo como dos tokens separados (según el criterio de falta de buena formación), consulte http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52538 así que para futuras versiones de gcc (4.8 rama, creo) el código existente funcionará nuevamente.
Este codigo
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc,char **argv)
{
uint64_t val=1234567890;
printf("%"PRId64"/n",val);
exit(0);
}
Funciona para C99 , C++03 , C ++ 11 según GCC 4.5 , pero falla en C ++ 11 según GCC 4.7.1 . Agregar un espacio antes de PRId64
permite que GCC 4.7.1 lo compile.
¿Cuál es la correcta?