未记录的 C++ 预处理器指令 (MSVC 2013u4)

Undocumented C++ preprocessor directives (MSVC 2013u4)

在 MS 文件 apiset.h 中,有以下预处理器指令:

#define API_SET_BY_ORDINAL(X,O,PO)         X @##O NONAME

MS help page recognizes the stringify, charizing, and token-pasting preprocessor commands. '@' is not one of the 96 accepted characters,而在 MSVC 中,'##' 之前的 '@' 不能出现在标识符中。

整个“@##”是预处理器命令吗?如果是这样,它的目的是什么?如果不是,应该如何理解上面的宏?

Microsoft C/C++ 编译器从未要求 ## 预处理运算符的结果是有效的预处理标记。 @##O 的目的是在 O 给出的数字前面粘贴一个 @ 字符,中间没有任何空格。所以 API_SET_BY_ORDINAL(GetSystemTime, 633, x) 将扩展为 GetSystemTime @633 NONAME。此宏不打算在 C/C++ 代码中使用,而是用作模块定义 (.DEF) 文件中 EXPORT statement 的一部分。

虽然这个宏是新的,但其他不生成有效预处理令牌的## 示例已经在 Microsoft 的 header 中存在很长时间了。例如,我可以在 2000 年 7 月发布的 Platform SDK header 中的 header 中找到以下行,这是我手头上最旧的版本:

#define _VARIANT_BOOL /##/

请注意,// 不是有效的预处理标记。由于没有 // 运算符,因此它是两个单独的预处理标记。