[英]C99 printf formatters vs C++11 user-defined-literals
这段代码:
#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);
}
根据GCC 4.5 ,适用于C99 , C ++ 03 , C ++ 11 ,但根据GCC 4.7.1 ,在C ++ 11上失败。 在PRId64
之前添加空格让GCC 4.7.1编译它。
哪一个是正确的?
gcc 4.7.1是正确的。 根据标准,
2.2翻译阶段[lex.phases]
1 - 翻译语法规则的优先顺序由以下阶段指定。 [...]
3.源文件被分解为预处理标记(2.5)和空白字符序列(包括注释)。 [...]
4.执行预处理指令,扩展宏调用,[...]
并且每2.5个预处理标记[lex.pptoken] , user-de fi ned-string-literal是一个预处理标记生成:
2.14.8用户定义的文字[lex.ext]
user-de fi ned-string-literal :
string-literal ud-suffix
ud-suffix :
识别码
因此PRId64
的第4阶段宏扩展是无关紧要的,因为"%"PRId64
已被解析为单个用户定义的字符串文字预处理标记,由字符串文字 "%"
和ud后缀 PRId64
。
哦,这真是太棒了 ; 每个人都必须改变
printf("%"PRId64"\n", val);
至
printf("%" PRId64"\n", val); // note extra space
然而! gcc和clang同意将后缀上没有前导下划线的用户定义的字符串文字视为两个单独的标记(根据非良好格式标准),请参阅http://gcc.gnu.org/bugzilla/show_bug.cgi?id = 52538因此对于gcc的未来版本(我认为4.8分支),现有代码将再次运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.