Question

For instance, is the following possible:

#define definer(x) #define #x?
Was it helpful?

Solution

Though your syntax is invalid, the answer to your question is technically yes. But it can only be accomplished by nasty tricks that make your code unreadable and unmaintainable.

See also: http://www.ioccc.org/years.html#1995_vanschnitz and http://www.ioccc.org/years.html#2004_vik2

OTHER TIPS

No, you can't do that.
The pound (#) symbol has a different meaning while in a definition. it means - if this is an argument, make it a string by quoting it.

You cannot nest C preprocessor directives. Luckily, it is almost never necessary. If you really need that kind of power, you will almost certainly be better off with another preprocessor that you run before handing off the code to the C compiler. For example:

sed 's/@CUSTOMER@/J. Random Person/' foo.c.in > foo.c
cc foo.c

Another useful trick is to isolate the trickery into a single header file, which is generated by a program you write yourself:

./generate-trickery --greet 'J. Random Person' > foo.h

where foo.h will look like something like this:

#define GREET(x) ("J. Random Person greets you, " #x)

If you tie this together with a Makefile, or some other automation, it will be pretty seamless and not trip up your development much.

No, you can't do that.

You can reference one macro from another, but you cannot define one macro from another.

If you are trying to create a segment of preprocessor code that can be called multiple times to perform slightly different things, one (moderately awful) way you can do this is to isolate the code into a single .h file which you then #include several times. The idea is that each time you #include the file you are "calling your routine" -- you "pass arguments" by first #defineing certain preprocessor constants that the included file refers to.

One place where I've seen this be useful is in generating "smart" enumerations that can convert to/from their "stringized" forms (which is useful for I/O). You create a .h file containing e.g.

ENUMVAL(foo)
ENUMVAL(bar)
ENUMVAL(baz)

and then later #include this file twice: once where ENUMVAL() is defined in such a way as to create an enum declaration, and once when ENUMVAL() is defined in such a way as to produce an array of stringized names. By doing it this way, you don't need to specify the list of actual tokens more than once.

#define definer(x) #define #x?

#x is a stringification of x. You can't #define a string token. (#define "foo".) It has to be an identifier [a-zA-Z0-9_]* token.

You can't nest #define's like that. You can't have a #define in a #define.

You can have #if's inside #if blocks.

#ifdef FOO

#ifdef BAR
 ...
#else // BAR
 ...
#endif // BAR

#else // FOO
 ...
#endif //FOO

You are also somewhat limited as to the expressions you can use in #if macros. But you can sometimes work around that. For example:

        /* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4(      a,b,c,d)  CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d)  a ## b ## c ## d

    /* Creates a typedef that's legal/illegal depending on EXPRESSION.       *
     * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*".              *
     * (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT)                     \
  typedef char CONCATENATE_4( static_assert____,      IDENTIFIER_TEXT,  \
                              ____failed_at_line____, __LINE__ )        \
            [ (EXPRESSION) ? 1 : -1 ]

Plus something like:

STATIC_ASSERT( sizeof(int1) == 1, sizeof_int1_equal_1 );

(Yes, I know about #include <stdint.h>. It's just an example.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top