This answer to another question is relevant.
When you do weird preprocessor tricks (which are legitimate) it is useful to ask the compiler to generate the preprocessed form (e.g. with gcc -C -E
if using GCC) and look into that preprocessed form.
In practice, for a source file foo.c
it makes (sometimes) sense to get its preprocessed form foo.i
with gcc -C -E foo.c > foo.i
and look into that foo.i
.
Sometimes, it even makes sense to get that foo.i
without line information. The trick here (removing line information contained in lines starting with #
) would be to do:
gcc -C -E foo.c | grep -v '^#' > foo.i
Then you could indent foo.i
and compile it, e.g. with gcc -Wall -c foo.i
; you'll get error locations in the preprocessed file and you could understand how you got that and go back to your preprocessor macros (or their invocations).
Remember that the C preprocessor is mostly a textual transformation working at the file level. It is not possible to macro-expand a few lines in isolation (because prior lines might have played with #if
combined with #define
-perhaps in prior #include
-d files- or preprocessor options such as -DNDEBUG
passed to gcc
or g++
). On Linux see also feature_test_macros(7)
A known example of expansion which works differently when compiled with or without -DNDEBUG
passed to the compiler is assert
. The meaning of assert(i++ > 0)
(a very wrong thing to code) depends on it and illustrates that macro-expansion cannot be done locally (and you might imagine some prior header having #define NDEBUG 1
even if of course it is poor taste).
Another example (very common actually) where the macro expansion is context dependent is any macro using __LINE__
or __COUNTER__
...
NB. You don't need Eclipse for all that, just a good enough source code editor (my preference is emacs but that is a matter of taste): for the preprocessing task you can use your compiler.