C 和 C++ 标准都包含这样的文本:如果字符串化操作未能生成有效的字符串文字标记,则行为未定义。在 C++11 中,这实际上是可能的,方法是在原始字符串文字中包含一个换行符。但包罗万象的东西一直存在于标准中。
在 UB 或格式错误的程序尚未发生的情况下,stringize 是否有任何其他方式可以产生 UB?
我有兴趣了解 C 或 C++ 的任何方言。我是 writing预处理器。
最佳答案
stringify (#
) 运算符仅对字符串常量中的 \
进行转义。事实上,\
在字符串常量之外没有特别的意义,除了在一行的末尾。因此,它是一个预处理 token (C 部分 6.4,C++ 部分 2.5)。
因此,如果我们有
#define Q(X) #X
然后
Q(\)
是一个合法的调用:\
是一个预处理 token ,它永远不会转换为 token ,所以它是有效的。但是你不能字符串化 \
;那会给你 "\"这不是有效的字符串文字。因此,上述行为是未定义的。
这是一个更有趣的测试用例:
#define Q(A) #A
#define ESCAPE(c) Q(\c)
const char* new_line=ESCAPE(n);
const char* undefined_behaviour=ESCAPE(x);
一个不太有趣的未定义字符串化的情况是字符串化参数太长而不能成为字符串文字。 (标准建议字符串文字的最大长度至少为 65536 个字符,但没有提及宏参数的最大长度,可能更大。)
关于c++ - 字符串化运算符失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17416256/