双哈希使用

Double hash usage

在 C99 6.10.3.3.(2) 中(我的高亮部分)

If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.

#include <stdio.h>
#define hash_hash(a, b) a ## b
#define mkstr(a) # a
#define in_between(a) mkstr(a)

void main(void)
{
    char p[] = in_between(a hash_hash(,) b);
    printf("%s", p);
}

输出:

a  b

我用 hash_hash(,) 描述了突出显示的短语,结果似乎与标准的表述一样正确。

但我想知道是否省略了逗号 ,,例如 hash_hash(),那么这是否与标准的解释(未定义行为)不同? placemaker 和 white-space 一样吗?

如果逗号 , 被省略,比如 hash_hash(),那么这与标准的解释(未定义的行为)是否不同? placemaker和white-space一样吗?

是的,如果用参数定义宏,参数必须用逗号分隔符分隔。尝试定义多参数宏否则会违反标准规则,并且不会编译:

Function-like macros can take arguments, just like true functions. To define a macro that uses arguments, you insert parameters between the pair of parentheses in the macro definition that make the macro function-like. The parameters must be valid C identifiers, separated by commas and optionally whitespace.

此外,

  • 因为此要求是 well defined,所以它不会是未定义行为的示例。
  • 参考段落中的这句话可选白色space , and 表示白色 space 可以与定界符一起使用,但单独作为定界符是不够的。

But I wonder if comma , is omitted, like hash_hash(), then does this differ from standard's explanation(undefined behavior)?

本例中的逗号是 function-like 宏调用语法的一部分。它分隔宏参数列表中的参数。 function-like 宏的调用必须为该宏的每个命名参数提供一个值,而使用 hash_hash()(没有逗号)则不会这样做。这将违反语言约束,因此不仅结果行为未定义,而且符合标准的 C 实现在遇到此类违规时有义务发出诊断信息。

And is the placemaker the same as white-space?

没有。您可以将地标概念化为 zero-length 预处理标记。这样的事情不能直接在源代码中表示。它既不是空格也不是缺少预处理标记。 “地标”很好地描述了它的性质和作用。

But I wonder if comma , is omitted, like hash_hash(), then does this differ from standard's explanation (undefined behavior)?

我认为相关部分是 C11 6.10.3/4 强调我的:

Constraints

If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition.

逗号会给出一个没有 pre-proc 标记的有效标识符列表,但如果没有它,标识符列表将与宏的参数数量不匹配。所以 hash_hash() 违反了约束,您应该会收到一条诊断消息。