双哈希使用
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()
违反了约束,您应该会收到一条诊断消息。
在 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, likehash_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()
违反了约束,您应该会收到一条诊断消息。