C99 printf 格式化程序与 C++11 用户定义的文本
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 是正确的。 根据标准,
C++11
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);
自
printf("%" PRId64"n", val); // note extra space
然而! GCC 和 Clang 已同意将后缀上没有前导下划线的用户定义字符串文字视为两个单独的标记(根据非良好格式标准),请参阅 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52538 以便 gcc 的未来版本(我认为 4.8 分支)现有代码将再次工作。
相关文章:
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- Visual C++(VS2017)中用户定义的转换不明确
- 使用用户定义的参数调用future/async并调用类方法
- 带有用户定义类的c++折叠表达式
- g++用户定义的动态链接库上的全局new和delete运算符
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 修改"std::set"中用户定义类型的值
- 参数包构造函数在类模板中隐藏用户定义的转换
- MAKE:找不到包含的用户定义的头文件?
- C++:用户定义的显式类型转换函数错误
- 从用户定义的类生成格式字符串?
- 为用户定义的类正确调用复制构造函数/赋值运算符
- C++ 向量与用户定义的类比较?(==, <, >)
- STL 用户定义的二进制操作
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 使用宏编译时使用用户定义的数学函数,或者仅使用 c++ 中标准数学库中的函数
- C++:用户定义的类,以成员字段作为地址