Hector
Hector

Reputation: 2534

Undocumented C++ preprocessor directives (MSVC 2013u4)

In MS file apiset.h, there is the following preprocessor directive:

#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, and in MSVC the '@' before the '##' cannot be in an identifier.

Is the whole '@##' a preprocessor command? If so, what is its purpose? If not, how one should understand the above macro?

Upvotes: 1

Views: 282

Answers (1)

Ross Ridge
Ross Ridge

Reputation: 39551

The Microsoft C/C++ compiler has never required that the result of the ## preprocessing operator be a valid preprocessing token. The intent of @##O is to paste a @ character in front of a number given by O without any spaces in between. So API_SET_BY_ORDINAL(GetSystemTime, 633, x) will expand to GetSystemTime @633 NONAME. This macro isn't meant to be used in C/C++ code, it's meant to be used as part of an EXPORT statement in a module definition (.DEF) file.

While this macro is new, other examples of ## that don't generate valid preprocessing tokens have been in Microsoft's headers for a very long time. For example I can find the following line in header from the July 2000 release of the Platform SDK header, the oldest version I have on hand:

#define _VARIANT_BOOL /##/

Note that // isn't a valid preprocessing token. Since there's is no // operator, it's two separate preprocessing tokens.

Upvotes: 5

Related Questions