Run preprocessor and keep directives - gcc

Is there a way I can run gcc -E to run the preprocessor but also to keep the #define, #include, other directives in the output (possibly as comments)? I thought I remembered seeing an option for this but I can't find it in the GCC Preprocessor Options page. I need this to track down where things are going wrong in a complex case involving lots of include files and macros.

The relevant options are listed under -dCHARS. -dD outputs macro definitions (both #define and #undef directives), -dI outputs #include directives, and they can be combined to -dDI.

Related

define gets ignored by target_compile_definitions

I am looking to build a library and I need to pass two defines to that build, but cmake's target_compile_definitions() scrambles them in a manner that renders them unusable.
The two defines are:
-D'_LIB_EXCEPTION_ABI=__attribute__((visibility("default")))'
-D'_LIB_FALLTHROUGH()=((void)0)'
Unfortunately, the first one gets translated to (in the command build line):
-D'_LIB_EXCEPTION_ABI="\__attribute__((visibility(\"default\")))'"
While the second one is missing altogether from the command line.
CMake has known limitations on what compile definitions could be.
Among these limitations are function-style definitions (_LIB_FALLTHROUGH()) and ones containing double quotes (").
Instead of attempting to overcome these limitations, it is recommended to create a separate header file with these compile definitions:
#define _LIB_EXCEPTION_ABI __attribute__((visibility("default")))
#define _LIB_FALLTHROUGH() ((void)0)
This header file could be included with -include compiler option (gcc) or /FI option (Visual Studio).

How to "weakly" #include a configuration file?

I'm writing library routines of which some characteristics can be tailored through #include'ing a configuration file. However, I'd like this configuration file to be optional, some default parameters being provided in the source. Here is a typical source beginning:
#include "userconf.h"
#ifndef BUFSIZE
#define BUFSIZE 100
#endif
...
where file userconf.h, if it exists, contains:
#define BUFSIZE 255
Standard compilers (gcc or others) consider a missing #include file an error (and they're right!). In this case, and only for this line, I'd like the compiler to continue without objection since default values are provided for parameters expected from the missing configuration file.
Is there a way to do this?
Note: I don't mind checking for this existence of the file from the make system (I'm using CMake) and passing a -Doption if that's easier to do (but, please, provide CMake directives for it, I'm not familiar with it and open documentation gives a hard time to grab the whole picture).
I found the answer "by accident" when including the wrong file.
You make profit of the multiple include directory search feature of the compiler (aka. -I option). You arrange your -I option list in such a way that there is a directory, preferentially at the end of the chain, containing a skeletal version of the configuration file.
For example, directory default/ contains the following userconf.h:
#define BUFSIZE 255
and the developement directory develop/ contains the live userconf.h:
#define BUFSIZE 100
Then, the source file of the original question may be compiled with
gcc source.c -Idevelop -Idefault ...
and -Idevelop may be omitted if it is part of the default searched directories.

Pre-processing C code with GCC

I have some C source files that need to be pre-processed so that I can use another application to add Code Coverage instrumentation code in my file.
To do so, I use GCC (I'm using this on a LEON2 processor so it's a bit modified but it's essentially GCC 3.4.4) with the following command line:
sparc-elf-gcc -DUNIT_TEST -I. ../Tested_Code/0_BSW/PKG_CMD/MEMORY.c -E > MEMORY.i
With a standard file this works perfectly, but this one the programmer used a #ifndef UNIT_TEST close and no matter what I do the code won't be pre-processed. I don't understand why since I'm passing -DUNIT_TEST to GCC explicitly defining it.
Does anyone have any clue what could cause this? I checked the resulting .i file and as expected my UNIT_TEST code is not present in it so I get an error when instrumenting it.
Anything wrapped in an #ifndef will only be parsed if it's NOT defined so you need to remove that definition to get all the code that is inside that block. GCC can't spit out preprocessed info for all the #ifdef and #ifndef if at preprocessing times symbols are/aren't defined.

Preprocessor output

How do I view the output produced by the C pre-processor, prior to its conversion into an object file?
I want to see what the MACRO definitions do to my code.
gcc -E file.c
or
g++ -E file.cpp
will do this for you. The -E switch forces the compiler to stop after the preprocessing phase, spitting all it’s got at the moment to standard output.
Note: Surely you must have some #include directives. The included files get preprocessed, too, so you might get lots of output.
For Visual C++ the switch is /E which spits the preprocessor output to screen.
You can also call the C Preprocessor directly.
cpp infile outfile
Check out man cpp for more info.
For GCC,
gcc -E -dM file.c
or
g++ -E -dM file.cpp
should do the job. -dM, as GNU Preprocessor manual puts it, should generate a list of ‘#define’ directives for all the macros defined during the execution of the preprocessor, including predefined macros.
It depends on the compiler you use.
With GCC, you can specify the -E flag on the command-line to let the compiler produce the pre-processor output.
If using CLion by Jetbrains, you can use the action "clangd: Preprocess current TU"
So hit shift shift and start typing clangd...
Best assign it to a shortcut for simpler reuse in preferences->keymap:
Shout out to marcosbento
PS: TU means 'translation unit' (see here LLVM translation unit)
You can check out my script described here:
http://mosermichael.github.io/cstuff/all/projects/2011/09/16/preprocessor.html
It formats the preprocessor output into a (hopefully) readable html document: lines that are different due to preprocessor are marked in the file.

How to undefine a define at commandline using gcc

How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.

Resources