## Preprocessor Operator
## Preprocessor Operator
Page 1 of 6
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no
Take the 2-minute tour ×
registration required.
What are the applications of the ## preprocessor operator and gotchas to consider?
As mentioned in many of my previous questions, I'm working through K&R, and am currently into the preprocessor. One of the more
interesting things — something I never knew before from any of my prior attempts to learn C — is the ## preprocessor operator.
According to K&R:
The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion. If a parameter in the
replacement text is adjacent to a ## , the parameter is replaced by the actual argument, the ## and surrounding white space are
removed, and the result is re-scanned. For example, the macro paste concatenates its two arguments:
#define paste(front, back) front ## back
How and why would someone use this in the real world? What are practical examples of its use, and are there gotchas to consider?
UPDATE:
I accepted Brian R. Bondy's answer, but want to thank everyone who contributed — and hopefully will contribute more in the future.
Everything here was enlightening, and helped me understand this concept a bit better. I doubt I'll be using it any time soon, but just
knowing not only what it does, but that it is used — and widely, apparently — is tremendously helpful.
c preprocessor
13 Answers
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
//Note you need a WIDEN2 so that __DATE__ will evaluate first.
Here they want to use a 2 byte string instead of a 1 byte per char string.
This probably looks like it is really pointless but they do it for a good reason.
They use it with another macro that returns a string with the date and time.
--
#ifdef _UNICODE
#define _T(x) L ## x
#else
#define _T(x) x
#endif
--
#define MYLIB_ACCESSOR(name) (Get##name)
#define MYLIB_MODIFIER(name) (Set##name)
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015
c - What are the applications of the ## preprocessor operator and gotchas to consider? ... Page 2 of 6
Likewise you can use this same method for any other types of clever name
creation.
--
One thing to be aware of when you're using the token-paste (' ## ') or stringizing (' # ')
preprocessing operators is that you have to use an extra level of indirection for them to work
properly in all cases.
If you don't do this and the items passed to the token-pasting operator are macros themselves,
you'll get results that are probably not what you want:
#include <stdio.h>
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
#define BAD_PASTE(x,y) x##y
#define BAD_STRINGIFY(x) #x
#define SOME_MACRO function_name
int main()
{
printf( "buggy results:\n");
printf( "%s\n", STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
The output:
buggy results:
SOME_MACRO__LINE__
BAD_PASTE( SOME_MACRO, __LINE__)
PASTE( SOME_MACRO, __LINE__)
desired result:
function_name21
@MichaelBurr i was reading your answer & i have a doubt. How come this LINE is printing the line number?
– HELP PLZ Jun 26 '14 at 16:51
@AbhimanyuAryan: I'm not sure if this is what you're asking, but __LINE__ is a special macro name that is
replaced by the preprocessor with the current line number of the source file. – Michael Burr Jun 26 '14 at
19:16
Here's a gotcha that I ran into when upgrading to a new version of a compiler:
When the result of the token-pasting operator is not a valid preprocessor token, the token-
pasting operator is unnecessary and possibly harmful.
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015
c - What are the applications of the ## preprocessor operator and gotchas to consider? ... Page 3 of 6
For example, one might try to build string literals at compile time using the token-pasting
operator:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
1+2 std::vector
1 + 2 std :: vector
Fairly modern versions of GCC (>=3.3 or so) will fail to compile this code:
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
The solution is to omit the token-pasting operator when concatenating preprocessor tokens to
C/C++ operators:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
The GCC CPP documentation chapter on concatenation has more useful information on the
token-pasting operator.
Thanks - I wasn't aware of this (but then I don't use these preprocessing operators too much...). –
Michael Burr Oct 20 '08 at 1:12
2 It's called the "token pasting" operator for a reason - the intent is to end up with a single token when you're
done. Nice writeup. – Mark Ransom Apr 30 '09 at 18:17
When the result of the token-pasting operator is not a valid preprocessor token, the behavior is undefined. –
Alek Jun 30 '14 at 15:19
This is useful in all kinds of situations in order not to repeat yourself needlessly. The following
is an example from the Emacs source code. We would like to load a number of functions from
a library. The function "foo" should be assigned to fn_foo , and so on. We define the following
macro:
#define LOAD_IMGLIB_FN(lib,func) { \
fn_##func = (void *) GetProcAddress (lib, #func); \
if (!fn_##func) return 0; \
}
LOAD_IMGLIB_FN (library, XpmFreeAttributes);
LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
LOAD_IMGLIB_FN (library, XpmReadFileToImage);
LOAD_IMGLIB_FN (library, XImageFree);
The benefit is not having to write both fn_XpmFreeAttributes and "XpmFreeAttributes" (and risk
misspelling one of them).
You can use token pasting when you need to concatenate macro param with
something else.
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015
c - What are the applications of the ## preprocessor operator and gotchas to consider? ... Page 4 of 6
struct list_int {
int value;
struct list_int *next;
};
Link
My answer to that question showed how applying little preprocessor magic lets you define your
enumeration like this (for example) ...;
ENUM_BEGIN( Color )
ENUM(RED),
ENUM(GREEN),
ENUM(BLUE)
ENUM_END( Color )
... With the benefit that the macro expansion not only defines the enumeration (in a .h file), it
also defines a matching array of strings (in a .c file);
The name of the string table comes from pasting the macro parameter (i.e. Color) to
StringTable using the ## operator. Applications (tricks?) like this are where the # and ##
operators are invaluable.
I use it in C programs to help correctly enforce the prototypes for a set of methods that must
conform to some sort of calling convention. In a way, this can be used for poor man's object
orientation in straight C:
SCREEN_HANDLER( activeCall )
STATUS activeCall_constructor( HANDLE *pInst )
STATUS activeCall_eventHandler( HANDLE *pInst, TOKEN *pEvent );
STATUS activeCall_destructor( HANDLE *pInst );
This enforces correct parameterization for all "derived" objects when you do:
SCREEN_HANDLER( activeCall )
SCREEN_HANDLER( ringingCall )
SCREEN_HANDLER( heldCall )
the above in your header files, etc. It is also useful for maintenance if you even happen to want
to change the definitions and/or add methods to the "objects".
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015
c - What are the applications of the ## preprocessor operator and gotchas to consider? ... Page 5 of 6
#define ASSERT(exp) if(!(exp)){ \
print_to_rs232("Assert failed: " ## #exp );\
while(1){} //Let the watchdog kill us
I take it you mean by ‘non-standard’ that the compiler did not do string pasting but did do token pasting — or
would it have worked even without ## ? – PJTraill Jun 10 at 10:44
UNITTEST(test_name)
expands to:
void __testframework_test_name ()
The main use is when you have a naming convention and you want your macro to take
advantage of that naming convention. Perhaps you have several families of methods:
image_create(), image_activate(), and image_release() also file_create(), file_activate(),
file_release(), and mobile_create(), mobile_activate() and mobile_release().
Of course, a sort of "minimal version of objects" is not the only sort of naming convention this
applies to -- nearly the vast majority of naming conventions make use of a common sub-string
to form the names. It could me function names (as above), or field names, variable names, or
most anything else.
#define ADDR_LEFTSHIFT 0
#define ADDR_WIDTH 7
BITFMASK(ADDR)
#define LOG(msg) log_msg(__function__, ## msg)
#define LOG(msg) log_msg(__file__, __line__, ## msg)
The above "functions" logs message and shows exactly which function logged a
message.
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015
c - What are the applications of the ## preprocessor operator and gotchas to consider? ... Page 6 of 6
1 What were you trying to do with that? It would work just as well without the "##", since there is no need to
token-paste "," to "msg". Were you trying to stringify msg? Also, FILE and LINE must be in uppercase, not
lowercase. – bk1e Oct 19 '08 at 20:44
You're right indeed. I need to find the original script to see how ## was used. Shame on me, no cookie
today! – ya23 Dec 12 '08 at 9:59
http://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preproce... 25/06/2015