So, depending on how I decide to compile a program, I want to be able to execute a set of functions. This could normally be done with just a few variables and comparisons, but since I will be distributing it to systems that only have the ELF, it needs to be known at compile time what to run. Is it possible to pass in a custom gcc flag, say -flagset that makes it then set a MACRO in my code if that flag is set? I seen How to specify custom compiler flags for Visual Studio Compiler but that is a bit vague and not appropriate for my needs
From the gcc manual:
3.13 Options Controlling the Preprocessor
-D name
Predefine name as a macro, with definition 1.
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a ‘#define’ directive.
That is, you can set any macro value via the -D option and that will be seen by the code. Example:
gcc -DSOME_FLAG test.c
Then in the code it can be checked as such:
#ifdef SOME_FLAG
/* do code for SOME_FLAG enabled case */
#endif
Related
I am trying to learn preprocessor tricks that I found not so easy (Can we have recursive macros?, Is there a way to use C++ preprocessor stringification on variadic macro arguments?, C++ preprocessor __VA_ARGS__ number of arguments, Variadic macro trick, ...). I know the -E option to see the result of the preprocessor whole pass but I would like to know, if options or means exist to see the result step by step. Indeed, sometimes it is difficult to follow what happens when a macro calls a macro that calls a macro ... with the mechanism of disabling context, painting blue ... In brief, I wonder if a sort of preprocessor debugger with breakpoints and other tools exists.
(Do not answer that this use of preprocessor directives is dangerous, ugly, horrible, not good practices in C, produces unreadable code ... I am aware of that and it is not the question).
Yes, this tool exists as a feature of Eclipse IDE. I think the default way to access the feature is to hover over a macro you want to see expanded (this will show the full expansion) and then press F2 on your keyboard (a popup appears that allows you to step through each expansion).
When I used this tool to learn more about macros it was very helpful. With just a little practice, you won't need it anymore.
In case anyone is confused about how to use this feature, I found a tutorial on the Eclipse documentation here.
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.
The only way to see what is wrong with your macro is to add the option which will keep the temporary files when compilation completes. For gcc it is -save-temps option. You can open the .i file and the the expanded macros.
IDE indexers (like Eclipse) will not help too much. They will not expand (as other answer states) the macros until the error occures.
I have written some code using pre processor directives to skip some statements to be executed.But My C code inside main is interested to change previously #defined values and assign new values as per condition and also change the result of pre processed statements too during run time.In short I have to change the pre processed statements during run time. How can I do this?
In short I have to change the pre processed statements during run time
This is impossible. Read about C preprocessing & cpp. Compile-time and run-time are different (and the compiled code could even run on a different machine, read more about cross-compiling). If using GCC, use gcc -C -E foo.c > foo.i to preprocess your foo.c source file into foo.i preprocessed form (and then use an editor or a page to look inside that generated foo.i)
Perhaps you want to load additional code at runtime. This is not possible with pure C99 standard code. Perhaps your operating system offers dynamic loading. POSIX specifies dlopen. You might also want to use JIT compiling techniques to construct machine code at runtime, e.g. with libraries like GCCJIT, asmjit, GNU lightning, libjit, LLVM, ...
Read also about homoiconic languages. Consider coding in Common Lisp (e.g. with SBCL).
Perhaps you want to customize your GCC compiler with MELT.
Not possible. Preprocessing happens before compile-time.
The compiler only sees the result of the preprocessor, nothing more.
I was diving into the glibc source code and found quite a lot of usages of preprocessors like
#ifdef XXX
and
#if YYY
In order to know the exact behavior of the glibc that will be compiled and run on my machine, I have to know whether these flags are indeed defined or not. What I am currently doing is to insert the following piece of code to somewhere, compile, and run, which is neither elegant nor efficient.
#ifdef XXX
printf("XXX defined");
#endif
Anther way might be to grep the flag in the entire source tree, but I found this way not very reliable. Because sometimes I didn't find any #define XXX but I still got XXX defined printed out. (Can anyone let me know why?)
Therefore, I want to know what is the best practice to do this.
I found that combination of gcc with -g3 and gdb is pretty useful for checking macros and even macro-expansions for function-like macros. See man gcc and 12 C Preprocessor Macros from GDB manual for more details.
As more "invasive" way you could put #pragma message (or some similar) directive to examine individual macros during compilation:
Prints string as a compiler message on compilation. The message is
informational only, and is neither a compilation warning nor an error.
There is also -E switch, that allows to simply look into preprocessed translation unit.
This is probably a really stupid question, but how do I turn on these debug messages in my code?
#ifdef DEBUG_MSG
printf("initial state : %d\n", initial_state);
#endif
Many thanks in advance,
When compiling, try something like this:
$ gcc -DDEBUG_MSG -o foo foo.c
You would have to #define that somehow.
0. In your code.
Directly in your code somewhere before you use that flag:
#define DEBUG_MSG
1. On the command line.
For each sourcefile, or appropriately in your makefile:
gcc -DDEBUG_MSG main.c
(For gcc, the flag is -D<macro-name>, for MSVC, it is /D, for ICC it is one of the former, depending on your operating system. )
2. In your IDE, somewhere.
In your IDE's project settings, find where you can put definitions. Under the hood, this is done using 1.
#ifdef means 'If defined', your code essentially tells the preprocessor to check if DEBUG_MSG is defined somewhere else. If it is, it will include the code you've shown.
The C preprocessor phase will only pass code inside an #ifdef/#endif to the compiler phase if the symbol is defined.
You can generally do this in (at least) two ways.
The first is to use a command line switch for the compiler such as:
gcc -DDEBUG_MSG myprog.c
(-D means to define the pre-processor symbol following it and, although this is implementation-specific, many compilers use the same switch). The second is to place a line like:
#define DEBUG_MSG
inside your actual source code somewhere before the #ifdef.
The former is usually preferred since it allows you to control that behaviour without having to make changes to your source code so that, for example, you can have a debug and release build generated from the same source code.
#ifdef will make your macro to be expanded only if DEBUG_MSG is defined. You can do this in two ways. Either do a #define DEBUG_MSG 1 in your source or compile using -DDEBUG_MSG (if using gcc, there are similar flags for other compilers too)
Is it possible to get the list of #defines(both compile time and defined in the source code) used in a C program while execution.
Because i am having a project having lot of C source files.
Is there any compile time option to get that?
GNU cpp takes various -d options to output macro and define data. See their man pages for more details.
for gcc, you can use one of the following:
-dCHARS CHARS is a sequence of one or more of the following characters, and must not be preceded by a space. Other characters are interpreted by the compiler proper, or reserved for future versions of GCC, and so are silently ignored. If you specify characters whose behavior conflicts, the result is undefined.
M'
Instead of the normal output, generate a list of#define' directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command
touch foo.h; cpp -dM foo.h
will show all the predefined macros.
If you use -dM without the -E option, -dM is interpreted as a synonym for -fdump-rtl-mach. See Debugging Options.
D'
LikeM' except in two respects: it does not include the predefined macros, and it outputs both the #define' directives and the result of preprocessing. Both kinds of output go to the standard output file.
N'
Like `D', but emit only the macro names, not their expansions.
I'
Output#include' directives in addition to the result of preprocessing.
U'
LikeD' except that only macros that are expanded, or whose definedness is tested in preprocessor directives, are output; the output is delayed until the use or test of the macro; and `#undef' directives are also output for macros tested but undefined at the time.
In gcc the command you probably want is
gcc -dM -E [your_source_files]
I know this is implicitly in the above answers, but perhaps someone needs (like myself) the quick recipe.