在MS文件apiset.h中,有以下预处理程序指令:
#define API_SET_BY_ORDINAL(X,O,PO) X @##O NONAME
MS help page识别stringify,charizing和token-pasting预处理器命令。 '@'不是96 accepted characters之一,而在MSVC中,'##'之前的'@'不能在标识符中。
整个'@ ##'是预处理器命令吗?如果是这样,它的目的是什么?如果不是,应该如何理解上述宏?
答案 0 :(得分:3)
Microsoft C / C ++编译器从未要求##预处理运算符的结果是有效的预处理标记。 @##O
的目的是将@
字符粘贴到O
给出的数字前面,两者之间没有任何空格。因此API_SET_BY_ORDINAL(GetSystemTime, 633, x)
将扩展为GetSystemTime @633 NONAME
。这个宏不应该用在C / C ++代码中,它应该用作模块定义(.DEF)文件中EXPORT statement的一部分。
虽然这个宏是新的,但其他没有生成有效预处理令牌的##的例子已经在微软的标题中存在了很长时间。例如,我可以在2000年7月发布的Platform SDK标题中找到以下行,这是我手头上最早的版本:
#define _VARIANT_BOOL /##/
请注意,//
不是有效的预处理令牌。由于没有//
运算符,因此它是两个独立的预处理标记。