【问题标题】:What type of content is allowed to be used as arguments for C preprocessor macro?允许使用什么类型的内容作为 C 预处理器宏的参数?
【发布时间】:2018-02-17 18:31:16
【问题描述】:

老实说,我很了解 C 编程语言的语法,但对 C 预处理器的语法几乎一无所知,尽管我有时会在编程实践中使用它。

所以问题。假设我们有一个扩展为空的简单宏:

#define macro(param)

宏调用构造中可以放入的语法有什么限制?

在调用宏时肯定不能使用单个或多个逗号:

macro(,); // won't compile

但是,如果我们将逗号放在括号中,它将被 C 预处理器接受:

macro((,)); // compiles fine

当然不能使用注释字符:

macro(//); // compile error

因为据我所知,cmets 是由预处理器本身处理的。

使用宏时也不允许使用非封闭引号和圆括号:

macro("); // compile error

但是 C 语法中未使用的字符被很好地接受:

macro(@#$); // compiles

即使是外语字符也能正常工作:

macro(бла-бла-бла я пишу по-русски); // compiles too

我可以在调用宏时在花括号中使用随机有效的 C/C++ 代码吗?我可以使用没有大括号的随机有效 C/C++ 代码吗?以下代码似乎可以正常编译:

macro(int a = 5; printf("%d\n", a););

【问题讨论】:

  • 你需要阅读标准文档,那里会详细解释。如果您只是想学习,如果您想滥用预处理器,那么请接受以下建议:不要!请注意,例如,使用预处理器跨越多行代码会使调试变得非常困难,因为它将整个代码块扩展为单行。因此调试器会将同一行内的任何错误报告到代码块中,该代码块可以是多行(逻辑行可视行用分号分隔的段)。
  • @IharobAlAsimi:C 预处理器未包含在 C 标准中。
  • @MarkBenningfield 真的吗?让我确定一下。
  • @MarkBenningfield 你错了,C 标准涵盖了宏。
  • @MarkBenningfield Please take a look here.

标签: c c-preprocessor


【解决方案1】:

您不能通过您提出的方案传递任意文本以忽略:

  • C 预处理器将读取输入文件并将其解析为一系列预处理标记,在剥离 cmets 后,作为参数传递给宏。它匹配括号以确定哪些标记构成由, 分隔的参数。

  • 包含带有无法识别的转义序列或独立反斜杠的字符串或字符常量的文本不会被解析为标准预处理标记。 macro(@#$); 是否编译取决于实现。

  • 但是请注意,您可以通过将宏定义为采用可变数量的参数来解决, 问题:

    #define macro(...)
    

【讨论】:

  • 在预处理器开始工作之前,cmets 被移除(视为空格)。
猜你喜欢
  • 2013-03-14
  • 2012-05-27
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
相关资源
最近更新 更多