Q我有一个旧宏
#define CTRL(c) ('c' & 037),它似乎不再起作用了。
A此宏的预期用途是类似以下的代码
tchars.t_eofc = CTRL(D);预计会展开为
tchars.t_eofc = ('D' & 037);基于参数的实际值将被替换的假设c即使在字符常量的单引号内。预处理从来就不是这样工作的;像这样的CTRL()宏能工作,这多少有点意外。
ANSI C 定义了一个新的“字符串化”运算符(参见问题 11.17),但没有相应的“字符化”运算符。
解决这个问题的最佳方案可能是将单引号从定义移到调用,通过重写宏为
#define CTRL(c) ((c) & 037)并调用它为
CTRL('D')(这样做也使宏变得“句法化”;参见问题 10.2。)
也有可能使用字符串化运算符和一些间接寻址
#define CTRL(c) (*#c & 037)或
#define CTRL(c) (#c[0] & 037)但这两者都不如原始的宏好用,因为它们在case标签或全局变量初始化器中无效。(全局变量初始化器和case标签需要各种形式的常量表达式,而不允许使用字符串字面量和间接寻址。)
另请参见问题 11.18。
参考:ISO Sec. 6.8.3
H&S Secs. 7.11.2,7.11.3 pp. 226-7