c++ 我可以注解多行宏吗?

a6b3iqyw  于 2023-05-02  发布在  其他
关注(0)|答案(5)|浏览(183)

我正在编写一些大型宏,并认为如果我可以向它们添加注解会很好,就像这样:

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL() \ // this does...
  SOME_OTHER_FUNCTION_CALL()

当我运行它时,我得到:
程序cpp:9:2:错误:程序中的“\”
有什么方法可以解决这个问题吗?或者是不能注解多行宏吗?

cxfofazt

cxfofazt1#

除了宏的最后一行之外,没有办法在宏中使用// comments
正如Paul R所建议的,/* comment */确实有效,似乎是唯一的选择:

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL()  /* this does... */ \
  SOME_OTHER_FUNCTION_CALL()

原因如下。Standard for Programming Language C ++(我只能访问这个草稿)指定源文件的物理行可以连接成编译器将看到的逻辑行,方法是使用\后跟一个换行符:
反斜杠字符()后面紧跟换行符的每个示例都将被删除,从而拼接物理源行以形成逻辑源行。只有任何物理源行上的最后一个反斜杠才有资格成为这种拼接的一部分。
这可以在预处理器输出中轻松检查:创建file.cpp

pri\
ntf ("Hell\
o world"\
);

然后

cpp file.cpp

给予

printf ("Hello world");

printf 
    ("Hello world");

这是编译器看到的(在Ubuntu上检查;您的里程数可能会有所不同)。
现在,将此规则应用于多行宏,

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL() \
  SOME_OTHER_FUNCTION_CALL()

被预处理器理解为

#define SOME_BIG_MACRO(input)   SOME_FUNCTION_CALL()   SOME_OTHER_FUNCTION_CALL()

因为所有\和下一个换行符都被忽略。
与此类似,

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL()  /* this does... */ \
  SOME_OTHER_FUNCTION_CALL()

被预处理器视为

#define SOME_BIG_MACRO(input)   SOME_FUNCTION_CALL()  /* this does... */   SOME_OTHER_FUNCTION_CALL()

然而

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL()  \ // this does...
  SOME_OTHER_FUNCTION_CALL()

变成了两条线:

#define SOME_BIG_MACRO(input)   SOME_FUNCTION_CALL()  \ // this does...
  SOME_OTHER_FUNCTION_CALL()

因为第二个\后面没有换行符,因此被保留,并且换行符前面没有\。这会导致编译错误。

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL()  // this does... \
  SOME_OTHER_FUNCTION_CALL()

变成了一条线:

#define SOME_BIG_MACRO(input)  SOME_FUNCTION_CALL()  // this does...   SOME_OTHER_FUNCTION_CALL()

这在语法上是正确的,但是宏不完整。一些编译器将此报告为错误,因为这很可能不是程序员的意图。其他的,如Ubuntu cc,静默地应用标准定义的规则。
由于一个宏只能占用一个逻辑行(虽然有几个物理行,使用换行符转义机制),所以这一行上的任何// comment都会导致宏的所有其余部分被忽略。
结论:// comment只能出现在(多行或单行)宏的末尾,而/* comment */完全可以在宏内部使用。

wljmcqd8

wljmcqd82#

行注解//不行,只能阻止注解/*。.. */例如

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL() /* this does... */ \ 
  SOME_OTHER_FUNCTION_CALL()
oxiaedzo

oxiaedzo3#

根据这个答案:
https://stackoverflow.com/a/11722479/3545094
在预处理期间,在展开宏之前,注解将被一个空格字符替换。
\转义一个字符,必须是\n才能使宏工作,正如前面的答案/注解所解释的那样。
这意味着注解必须位于宏中的\之前,因此//将不起作用,因为您将删除宏工作所需的\。

8qgya5xd

8qgya5xd4#

可能是类似于

#define MY_MACRO(a, b, c) \
static_assert(true, "My comments go here..."); \
...
8cdiaqws

8cdiaqws5#

我假设一个块注解对你来说不起作用--不管是什么原因。作为一个快速而肮脏的解决方案,你可以只输入一个不使用的字符串文字:

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL(), (void)"this does..." \
  SOME_OTHER_FUNCTION_CALL()

这不是很好,可能会触发样式检查器(特别是。没有void铸件)。一个static_assert是严格更好的(cf.@Zinovy Nis的回答);但如果你碰巧需要支持C03或C98,就没有static_assert了。
由于您已经在使用宏,因此更好的替代方案可能是定义一个COMMENT宏,该宏忽略任何进入其中的内容,并且具有相当清晰的文档意图的优势:

#define COMMENT(x)
#define COMMENT(...) // C++11 and onward: No need for quotes!

在您的代码中:

#define SOME_BIG_MACRO(input)\
  SOME_FUNCTION_CALL() COMMENT("this does...") \
  SOME_OTHER_FUNCTION_CALL()

先说清楚我不推荐这些,我指出这些都是工作解决方案,“完成工作”,OP要求。

相关问题