Am using visual cl.exe compiler to get an intermediate file after preprocessing.
all the #define are removed. is there any possibility to keep them in the intermediate file?
No. One of the tasks of the preprocessing is to remove all #define and others preprocessing stuffs the #s and creates a plain c file.
What you can do:
use the /E or /P to output the preprocess to the output or file: http://blog.kowalczyk.info/article/clexe-cmd-line-args.html
#define is a preprocessor instruction so obviously it won't be present in a preprocessed source file. Every occurrence of a preprocessor constant will be replaced with its actual value by the preprocessor.
Related
For example:
#include "pathtoheader1/header1.hh"
##include "pathtoheader2/header2.hh"
What is the difference between these two preprocessor directives?
Edit
From what I can tell, the ##include directive, in the context of the program I am working with, will prepend -I flags to the specified include path.
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels
The compiler will now look for:
/models/pathtoheader1/header1.hh
instead of
/pathtoheader1/header1.hh
These flags are stored in a .mk file.
Additional Information
I am using NASA's Trick Simulation environment to build a simple 2-body simulation of the earth orbiting the sun. The specific tool I am using is called 'trick-CP', Trick's compilation tool.
https://github.com/nasa/trick
## is the token pasting operator in both the C and C++ preprocessors. It's used to concatenate two arguments.
Since it requires an argument either side, a line starting with it is not syntactically valid, unless it's a continuation of a previous line where that previous line has used the line continuation symbol \ or equivalent trigraph sequence.
Question is about NASA Trick. Trick extends C and C++ language with its own syntax.
From Trick documentation:
Headers files, that supply data-types for user-defined models should be included using ##include . Note the double hash (#).
The second one is a syntax error in C++, and I am pretty sure it is a syntax error in C too. The ## preprocessor operator is only valid inside a preprocessor macro (where it forces token pasting).
Here is what the Trick Documentation says about include:
Include files
There are two types of includes in the S_define file.
Single pound "#" includes.
Include files with a single pound "#" are parsed as they are part of the S_define file. They are treated just as #include files in C or C++ files. These files usually include other sim objects or instantiations as part of the S_define file.
Double pound "#" includes.
Include files with a double pound "##" are not parsed as part of the S_define file. These files are the model header files. They include the model class and structure definitions as well as C prototypes for functions used in the S_define file. Double pound files are copied, minus one pound, to S_source.hh.
Also here is a link to where it talks about it in the Trick documentation: https://nasa.github.io/trick/documentation/building_a_simulation/Simulation-Definition-File
Is there a way to use a preprocessor directive without using the # character in C code?
Can we echo the hash character somehow by using its ASCII etc. equivalents?
Eg: 1 can be echoed by using 'SOH' in the .c source file. Is there a similar hack for
'#'?
You can use the digraph or trigraph equivalent if your compiler supports them (you may need to pass flags to the compiler):
digraph: %:
trigraph: ??=
However, if you're trying to use preprocessor macros to generate preprocessor commands, there's no way to do that.
I have a set of includes that reside in a far off directory meaning that including them requires a long include, such as:
#include "../../Path/to/my/file.h"
Where I have multiple of these it becomes a bit inconvenient so I am thinking I may be able to use a #define for the directory path and then concat the file name that I need, i.e.
#define DIR "../../Path/to/my/"
#define FILE1 "file.h"
#define FILE2 "anotherFile.h"
#include DIR FILE1 // should end up same as line in first example after pre-proc
However this does not work... is there anyway to concatenate within the workings of the C pre-processor suitable for this?
The compiler will do macro replacement on an #include line (per C 2011 [N1570] 6.10.2 4), but the semantics are not fully defined and cannot be used to concatenate file path components without additional assistance from the C implementation. So about all this allows you to do is some simple substitution that provides a complete path, such as:
#define MyPath "../../path/to/my/file.h"
#include MyPath
What you can do with most compilers and operating systems is:
Tell the compiler what directories to search for included files (as with GCC’s -I switch).
Create symbolic links to other directories, so that #include "FancyStuff/file.h" becomes equivalent to ../../path/to/FancyStuff because there is a symbolic link named FancyStuff that points to the longer path.
You can't customise the search path for include files like this, but you can tell the compiler where to look for include files. Many compilers -I option for that, e.g.:
gcc -c stuff.c -I/path/to/my/ -I/path/to/other/
If that makes your compilation command too long, you should write a Makefile or, if you are working in Visual Studio or similar IDE, customise the search path in your project settings.
I want to include the #defines from a h file for parsing of all other files with Doxygen.
Project background:
My C project includes a header file config.h on it's the build command.
It also defines a target MODEL_A on the same build command.
config.h creates defines depending on the target being built (not the same lists of defines for MODEL_A as for MODEL_B):
#if defined(MODEL_A)
#define HAS_FUNCTIONALITY_1
#define HAS_FUNCTIONALITY_2
#elif defined(MODEL_B)
#define HAS_FUNCTIONALITY_3
#define HAS_FUNCTIONALITY_4
#endif
My issue with Doxygen:
I try to generate documentation with Doxygen. I have in the Doxyfile:
# including of config.h to INPUT seems necessary.
INPUT = ./source/config.h \
./source
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
INCLUDE_PATH = ./source
INCLUDE_FILE_PATTERNS = ./source/config.h
PREDEFINED = MODEL_A
The code that is dependent on the defines HAS_FUNCTIONALITY_x is not included in the documentation, as if the preprocessor did not get the defines in config.h.
My findings so far:
I inspected the preprocessor output with help of doxygen -d Preprocessor, and could see that:
./source/config.h was parsed first, and correctly according to MODEL_A (I can see the correct #defines in the preprocessor output). #define HAS_FUNCTIONALITY_1 figures in the preprocessor output.
the preprocessing of C files which depend on HAS_FUNCTIONALITY_1 act as if it was not defined.
Defining HAS_FUNCTIONALITY_1 in the field PREDEFINED of the Doxyfile works as expected. This is not a practical solution, but still interesting.
How do I make sure that the #define rows that are preprocessed first from config.h stay defined when the preprocessor works on all subsequent C files?
It would probably be beneficial for you to show the C code itself. In general, Doxygen runs a standard preprocessor - i.e. the rendered code should be the same as if the compiler preprocessed it. In order to achieve the equivalent of #define HAS_FUNCTIONALITY_1 in the code - it has to be defined.
I understand from your reluctance to add it to the doxygen configuration that it is defined somewhere else in the project (or perhaps the Makefile) and that that is the reason that the actual code acts as though it was defined.
If this is the case, I don't see a plausible workaround other than more preprocessor trickery or simply adding it in the doxygen config file.
I ran into a very similar issue.
My headers were in a different directory from my source, e.g.:
doxy_input_dir/
|
+ src/
|
+ inc/
I had RECURSIVE input file option set to YES. I assumed the preprocessor would correctly find my headers. However, when I viewed the preprocessor output by running doxygen -d Predefined <doxyfile> I saw a lot of #include foo.h: not found! skipping....
The solution was to specify all of the header directories explicitly using the INCLUDE_PATH tag.
If I have a C file foo.c and while I have given -DMACRO=1 as command line option for compilation. However, if within the header file also I have
#define MACRO 2
Which of these will get precedence?
I'm making an assumption of what you're doing, but if you'd like to supply from the command-line a non-default value for that macro, try this for the macro definition:
#ifndef MACRO
#define MACRO 2
#endif
That way if the MACRO has already been defined (via command-line parameter) it will neither be redefined nor result in an error.
The command line options apply ahead of any line read from a file. The file contents apply in the order written. In general, you will get at least a warning if any macro is redefined, regardless of whether the command line is involved. The warning may be silenced if the redefinition doesn't matter, perhaps because both definitions are identical.
The right way to answer a question like this is to build a small test case and try it. For example, in q3965956.c put the following:
#define AAA 2
AAA
and run it through the C preprocessor, perhaps with gcc -E:
C:>gcc -DAAA=42 -E q3965956.c
# 1 "q3965956.c"
# 1 ""
# 1 ""
# 1 "q3965956.c"
q3965956.c:1:1: warning: "AAA" redefined
:1:1: warning: this is the location of the previous definition
2
C:>
You can see from the output that the macro expanded to the value given by the #define in the file. Furthermore, you can see from the sequence of # directives that built-in definitions and the command line were both processed before any content of line 1 of q3965956.c.
Defines are stored in order the compiler sees them, and when the compiler encounters a new macro with the same name, it overwrites the previous macro with the new one (at least this is the case in gcc). GCC will also give you a warning when this happens.
You'll get an error for macro redefinition. Obviously -D gets defined first (before the source file is parsed rather than after) or it would have no use. The #define is then a redefinition.
manual says: first all -D and -U are evaluated in order and then all -includes (under section -D)
best way: try it out.