C++ C99 printf格式化程序与C++;11用户定义的文字

C++ C99 printf格式化程序与C++;11用户定义的文字,c++,c++11,printf,c99,code-translation,C++,C++11,Printf,C99,Code Translation,此代码: #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); } \defi

此代码:

#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);
}
\define\u STDC\u FORMAT\u宏
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
uint64_t val=1234567890;
printf(“%”PRId64“\n”,val);
出口(0);
}
适用于,但在上失败。在
PRId64
之前添加空格可以让GCC 4.7.1编译它


哪一个是正确的?

gcc 4.7.1是正确的。按照标准,

2.2翻译阶段[法律阶段] 1-翻译语法规则的优先顺序如下所示: 阶段。[…]
3.源文件分解为预处理标记(2.5)和空白字符序列 (包括评论)。[…]
4.执行预处理指令,展开宏调用,[…]

根据2.5预处理令牌[lex.pptoken],用户定义的字符串文字是预处理令牌产品:

2.14.8用户定义的文字[lex.ext] 用户定义的字符串文字:
字符串文字ud后缀
ud后缀:
标识符

因此,
PRId64
的第4阶段宏扩展是不相关的,因为
“%”PRId64
已经被解析为单个用户定义的字符串文字预处理标记,由字符串文字
“%”和ud后缀
PRId64
组成

哦,这将是可怕的;每个人都必须改变

printf("%"PRId64"\n", val);



然而!gcc和clang已同意将后缀上没有前导下划线的用户定义字符串文本视为两个单独的标记(根据非良好格式标准),有关gcc的未来版本(我认为是4.8分支),请参见so),现有代码将再次工作

但在处理平台ifdef之前,究竟如何定义/解析用户定义的文本?UDL可以做所有的
constexpr
工作,对吗?@rubenvb很好
constexpr
是一个第7阶段的过程。@rubenvb-ah-right;没有宏替换可以命中的东西<代码>“%”PRId64
是单个令牌。单击。如何用空格书写它:
printf(“%”PRId64“\n”,val)
无论如何都是更好的样式,但它仍然是一种破坏现有代码的更改。顺便说一句,ud后缀(不以下划线开头)保留用于将来的标准化,因此该程序“格式错误,不需要诊断”。参考:2.14.8p10和17.6.4.3.5“lit”\u udl是C++11中的单个标记。因此,它位于预处理器之前。实际上,打印未签名需要PRIu64,而不是PRId64(通常PRI{o,u,x,x}N表示未签名,PRI{i,d}N表示已签名)
printf("%" PRId64"\n", val);     // note extra space