There is no good answer to this question. If the values are
integers, a well-known trick using exclusive-OR could perhaps be
used, but it will not work for floating-point values or
pointers, or if the two values are the same variable (and the
"obvious" supercompressed implementation for integral types
a^=b^=a^=b
is in fact illegal due to multiple side-effects; see
questions 4.1 and 4.2). If the macro is intended to be used on values of
arbitrary type (the usual goal), it cannot use a temporary,
since it does not know what type of temporary it needs, and
standard C does not provide a typeof
operator.
The best all-around solution is probably to forget about using a macro, unless you're willing to pass in the type as a third argument.
#define Paste(a, b) a/**/b
That comments disappeared entirely and could therefore be used
for token pasting was an undocumented feature of some early
preprocessor implementations, notably Reiser's. ANSI affirms
(as did K&R) that comments are replaced with white space.
However, since the need for pasting tokens was demonstrated and
real, ANSI introduced a well-defined token-pasting operator, ##
,
which can be used like this:
#define Paste(a, b) a##b
(See also question 5.4.)
References: ANSI Sec. 3.8.3.3 p. 91, Rationale pp. 66-7.
The usual goal is to write a macro that can be invoked as if it were a single function-call statement. This means that the "caller" will be supplying the final semicolon, so the macro body should not. The macro body cannot be a simple brace- delineated compound statement, because syntax errors would result if it were invoked (apparently as a single statement, but with a resultant extra semicolon) as the if branch of an if/else statement with an explicit else clause.
The traditional solution is to use
#define Func() do { \ /* declarations */ \ stmt1; \ stmt2; \ /* ... */ \ } while(0) /* (no trailing ; ) */
When the "caller" appends a semicolon, this expansion becomes a single statement regardless of context. (An optimizing compiler will remove any "dead" tests or branches on the constant condition 0, although lint may complain.)
If all of the statements in the intended macro are simple expressions, with no declarations or loops, another technique is to write a single, parenthesized expression using one or more comma operators. (See the example under question 6.10 below. This technique also allows a value to be "returned.")
References: CT&P Sec. 6.3 pp. 82-3.
It's a question of style, and thus receives considerable debate. Many people believe that "nested #include files" are to be avoided: the prestigious Indian Hill Style Guide (see question 14.3) disparages them; they can make it harder to find relevant definitions; they can lead to multiple-declaration errors if a file is #included twice; and they make manual Makefile maintenance very difficult. On the other hand, they make it possible to use header files in a modular way (a header file #includes what it needs itself, rather than requiring each #includer to do so, a requirement that can lead to intractable headaches); a tool like grep (or a tags file) makes it easy to find definitions no matter where they are; a popular trick:
#ifndef HEADERUSED #define HEADERUSED ...header file contents... #endif
makes a header file "idempotent" so that it can safely be #included multiple times; and automated Makefile maintenance tools (which are a virtual necessity in large projects anyway) handle dependency generation in the face of nested #include files easily. See also section 14.
sizeof
operator work in preprocessor #if directives?
No. Preprocessing happens during an earlier pass of compilation, before type names have been parsed. Consider using the predefined constants in ANSI's <limits.h>, if applicable, or a "configure" script, instead. (Better yet, try to write code which is inherently insensitive to type sizes.)
References: ANSI Sec. 2.1.1.2 pp. 6-7, Sec. 3.8.1 p. 87 footnote 83.
You probably can't. (Preprocessor arithmetic uses only long ints, and there is no concept of addressing.) Are you sure you need to know the machine's endianness explicitly? Usually it's better to write code which doesn't care.
cpp is not intended as a general-purpose preprocessor. Rather than forcing it to do something inappropriate, consider writing your own little special-purpose preprocessing tool, instead. You can easily get a utility like make(1) to run it for you automatically.
If you are trying to preprocess something other than C, consider using a general-purpose preprocessor (such as m4).
#ifdef
's for
my taste. How can I preprocess the code to leave only one
conditional compilation set, without running it through cpp and
expanding all of the #include
's and #define
's as well?
There are programs floating around called unifdef, rmifdef, and scpp which do exactly this. (See question 17.12.)
There's no standard way, although it is a frequent need. The most expedient way is probably to extract printable strings from the compiler or preprocessor executable with something like the Unix strings(1) utility.
One popular trick is to define the macro with a single argument, and call it with a double set of parentheses, which appear to the preprocessor to indicate a single argument:
#define DEBUG(args) (printf("DEBUG: "), printf args) if(n != 0) DEBUG(("n is %d\n", n));
The obvious disadvantage is that the caller must always remember
to use the extra parentheses. Other solutions are to use
different macros (DEBUG1
, DEBUG2
, etc.) depending on the number
of arguments, or to play games with commas:
#define DEBUG(args) (printf("DEBUG: "), printf(args)) #define _ , DEBUG("i = %d" _ i)It is often better to use a bona-fide function, which can take a variable number of arguments in a well-defined way. See questions 7.1 and 7.2.