I have a large base of code for a series of embedded devices. Everytime we make a fix for one product, we merge-in the changes for others. Sometimes, some devices have the code under Macro's .. something like
#if DEVICE1
Do_This();
#elif DEVICE2
Do_That();
#else
Do_SomethingElse();
#endif
In the above case, I will have to merge-in the code under resspective macro. Sometimes, it is not very stright forward. So, after merging-in the changes.
During compilation time, is there any way to find whether the new added lines of code getting compiled or not?
cpp is the same preprocessor used by gcc. Call it manually with the same flags, it will output resulting (processed) code. Search interesting area to check what you want.
E.g. cpp foo.c | less.
Related
I'm making a firmware for an embedded device and when I build for different hardware I use different config settings.
For this I have a config file config.h:
#define FOO_MODE 7
In my code I would then use something like
void do_something_if_in_mode_4() {
if (FOO_MODE == 4)
return;
// ...
}
But CLion understands the config file as code and tells me that the "Condition is always false" and that return is unreachable code.
That file is code! The preprocessor included that file's content in your main source code and replaced all occurrences of FOO_MODE with 4. The compiler never sees FOO_MODE; remember that the preprocessor is dumb string handling that happens completely before the compiler gets to see the source code
And your compiler correctly detects the unreachable code, because 7 is not 4. The compiler will also be smart enough to omit the unreachable code in the binary, which is desirable.
If the warning annoys you, I'm sure there's ways to disable it. However, I think it's a good tool, so I'd keep it.
For code that you really do not even want to compile for some devices, try to use preprocessor #if instead, to effectively remove the text from the code that the compiler gets to see.
I want to know if it is possible to select different parts of my Fortran 95 routine to compile.
For example, if I pass certain flag to gfortran, then the compiler chooses which section to use for a certain function. I know I can do it using if inside the routine, but the drawback is that I don't want the program to run the if all the time due to speed concerns. I suppose solution should be similar to this one
I am working specifically with a program that calculates energies in a many-body system (say, a million). Then I don't want to put an if each time that I need to use a different energy definition at compilation time.
I hope this is possible and that my question is clear.
You can use the C like preprocessor. The -cpp command line option to your command line. That option is not turned on by default (As per Vladimir F comment below), although it looks like using the .F90 filename extension (i.e. capital F, instead of .f90) will do the trick without the -cpp option.
Details about the option:
https://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html
Then you can do the same as you pointed out, so the:
#ifdef <some-var>
code when <some-var> is true
#elif defined(<other-var>)
code when <other-var> is true
#endif
As required.
There are more examples on this page with actual code.
Also, like with C/C++, you can define macros on your command line with the-D option:
gfortran -DCASE1=3 ...
This will define CASE1 with the value 3. If you do not specify the value, then 1 is automatically assigned to the macro. This is documented on the same page.
I'm looking for a simple way to localize certain g++ (g++-4.9 to be specific) compile options to certain lines of code or at least targeted functions. I'm interested generally speaking, but also specifically to the -fast-math, -ffinite-math-only and -fno-signed-zeros options.
I presume that localization at the *.cpp file level is possible with make utility, but I'm hoping there is a way to enable it in the code itself, through #pragma or __attribute__ or something. I want to do this not only to minimize dependencies to external files (i.e. risk of incorrect makefile) but also to hopefully hyperlocalize certain FP behavior to specific equations within a function.
Alternatively, if localization of FP behavior by inline directives is NOT possible, what can I do to at least trigger a compile time error if desired compiler directive is NOT enabled in project build (e.g. makefile is lost or inappropriately modified).
I would presume that such inline optimization might be compiler specific, g++ in this case, but that is a compromise I'm willing to take.
In gcc you can use function attribute optimize:
void f () __attribute__ ((optimize("fast-math"), optimize("finite-math-only"), optimize("no-signed-zeros")));
I'm not sure that you are using the "localize" word correctly. Localization is related to adapting software to users of different human languages (French, Russian, Chinese...)
Perhaps you want to ask the compiler to optimize some functions with other optimization flags.
This is possible using #pragma GCC optimize etc... or using some function attributes
You might be able to turn on some bits of this with the fpmath option in a function attribute, but this was not clear to me from the docs. In light of that, I will focus on detection instead:
-fast-math already turns on -ffinite-math-only, so you don't need to worry about that. The docs for -fast-math say:
This option causes the preprocessor macro FAST_MATH to be
defined.
Which means it can be detected via
#ifndef __FAST_MATH__
#error "The -fast-math compiler option is required"
#endif
I have not yet found a compile-time way to detect the presence of -fno-signed-zeros
I've recently discovered clang++'s static analyzer feature, and it's fantastic for going over my code with a fine-toothed comb to find latent bugs. I just uncomment this line in my Makefile:
CXXFLAGS += --analyze -Xanalyzer -analyzer-output=text
et voila, I'm in deep-bug-checking mode.
One minor problem with this, however, is that whenever the analyzer does not find any problems in a particular .cpp file, doesn't produce any .o file.
Normally that wouldn't be a big deal (I can always re-comment the above line to build an actual executable), but usually when I see an analyzer-warning, the first thing I want to do is try to fix the underlying problem and then re-run make.
... which works, but since no .o files are being generated, make will start re-analyzing all the .cpp files again from the beginning, rather than just the .cpp files I actually modified since the previous run. This means I end up spending rather a lot of time re-checking .cpp files that haven't changed.
My question is, is there any way to get the static analyzer to output a .o file (it doesn't have to be a valid object file, just any file with an updated timestamp) so that Make will know that a "clean" .cpp file does not need to be re-processed? (i.e. make Make work the same way it does when doing a normal compile)
Check out the clang static analyzer page, and get the package there for download. You can use the included scan-build tool to do what you're trying.
The normal way to use is to get rid of the flags you have above and just run:
$ scan-build make whatever
And it should 'just work'. You might need to pass some more flags or set some environment variables if you don't use standard make variable names.
As we know, during debugging gdb could expand macro when special gcc options enabled.
But it is not convenient enough compared with debugging raw source code.
If there is a tool to expand macro in-place and replace the original source code for gcc to compile, that would be cool
If there is no such a tool, I'm going to create one and here are some rough ideas for your comments
Using "gcc -E" to compile the source code with macros and output the result to some temporary files, make some smart diff/compare between pre-processed file with original source file to extract the expanded source code and build a final source code whose macros have been expanded
One idea would be to use gcc -E, then edit the resulting .i file and remove the #line directives around the affected area. Then compile the .i file.
gcc+gdb could be made to debug macros as if they were inline functions, but I think that would be a fair amount of work in gcc.