gcc: warn if macro was redefined (regardless of previous definition) - gcc

gcc's manual says the following:
If a macro is redefined with a definition that is not effectively the same as the old one, the preprocessor issues a warning and changes the macro to use the new definition. If the new definition is effectively the same, the redefinition is silently ignored. This allows, for instance, two different headers to define a common macro. The preprocessor will only complain if the definitions do not match.
(emphasis mine)
Is there a way to make gcc more strict and issue a warning when a macro is redefined, regardless of definition?
Example:
#define TEST 1
#define TEST 1
int main(void) {
return 0;
}
Compiling with gcc -Wall -Wextra -Wpedantic does not generate any warning whatsoever.

Techincally speaking, if a header defines an apple as being red, then another wants to make sure everybody knows the apple is red, this should not be an issue. This is the reason behind it. And also to not compromise linking between multiple libraries if they have the same macro definition and the same value.
some h/hxx/hpp header
#define apples red
It's the usual attitude when you see some people wanting to make sure everyone knows they know (we all have these friends or co-workers, don't we? :) ) that apples are red so they state the obvious.
Preprocessor definitions are "compiled" (so-to-speak, rather said, interpreted and replaced or evaluated accordingly) at, well, compile-time. So having the same token defined multiple times is no real overhead on the app, it might just add a bit of compilation time.
The problem is when some wise-guy wants to let you know apples can also be green.
some other h/hxx/hpp header
#define apples green
Then, when you need to use some apples, you end up with:
some c/cxx/cpp file
#include "some_header.h/hxx/hpp"
#include "some_other_header.h/hxx/hpp"
And you end up with "apples " redefined.
Putting aside the daunting task of seeing where the conflict comes from (usually when combining multiple third-party libs/framerworks that might use similar names in macros or have the same acronyms prefixing a macro), this should be enough for you to know there is a conflict.
Keep in mind, this is a warning, so it will not stop the compilation. To treat warnings as errors, use -Werror.
I wouldn't worry about duplicate definitions, to be honest. They won't harm the code. If you really wanna go overkill-mode, you can always do some testing:
#if defined(apples) ...
... or ...
#ifdef apples ...

Related

Conditional compilation in gfortran

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.

Localize g++ compile options within code

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

#defining something as #error

In the process of getting rid of old macros in our code, I need to define the old macro as an error with a meaningful compiler message.
E.g., old code:
#define DIVIDE_BY_TWO(x) x/2
In the new code, to prevent the usage of this macro I'd like to write:
#define DIVIDE_BY_TWO(x) #error DIVIDE_BY_TWO is obsolete, use DIV_2 instead
But when I compile the above line I get:
error C2162: expected macro formal parameter
What is the correct way to do it?
A macro can't have directives or change the preprocessor state. You could leave DIVIDE_BY_TWO undefined, but then it doesn't help to find the replacement macro. The only way to do it portably is to define it as something like this:
#define DIVIDE_BY_TWO error_DIVIDE_BY_TWO_is_obsolete_use_DIV_2_instead
Which should give an error that error_DIVIDE_BY_TWO_is_obsolete_use_DIV_2_instead is not defined and hopefully that will give enough hints has to how to replace it.
The problem with using #error is that creates an error at the time that part of the code is analyzed by the preprocessor. You want to create an error when the macro is expanded. You can't, unfortunately, use #error for that.
I don't believe there is a way to generate a clear human-readable error message reliably in portable C. (You can, of course, make the macro expand to something that's syntactically invalid, though, which will at least stop compilation.) gcc supports doing it with _Pragma. Your question is effectively equivalent to this question and the answer there explains how to use _Pragma as well as other options for creating a fatal error.
You cannot use a preprocessor directive in #define since what you're asking for is to run the preprocessor twice.
If a line begins with an # it is a directive to the preprocessor and would be interpreted. If it doesn't, then it is subjected to macro substituion and replacement if such a macro exists.
The best you could do is to define the deprecated macro as some expression that would return an error for sure.

Go language warnings and errors

It seems that GO language does not have warnings in it. I've observed
few instances.
1. "declared and not used"(if variable is declared and not used
anywhere it gives an error and does not compile the program)
2. "imported and not used"(similarly if package is imported and not
used anywhere it gives an error and does not compile the program)
Can somebody help. If they have any pointers.
Go is trying to prevent this situation:
The boy is smoking and leaving smoke rings into the air. The girl gets
irritated with the smoke and says to her lover: "Can't you see the
warning written on the cigarettes packet, smoking is injurious to
health!"
The boy replies back: "Darling, I am a programmer. We don't worry
about warnings, we only worry about errors."
Basically, Go just wont let you get away with unused variables and unused imports and other stuff that is normally a warning on other languages. It helps put you in a good habit.
The Go Programming Language
FAQ
Can I stop these complaints about my unused variable/import?
The presence of an unused variable may indicate a bug, while unused
imports just slow down compilation. Accumulate enough unused imports
in your code tree and things can get very slow. For these reasons, Go
allows neither.
When developing code, it's common to create these situations
temporarily and it can be annoying to have to edit them out before the
program will compile.
Some have asked for a compiler option to turn those checks off or at
least reduce them to warnings. Such an option has not been added,
though, because compiler options should not affect the semantics of
the language and because the Go compiler does not report warnings,
only errors that prevent compilation.
There are two reasons for having no warnings. First, if it's worth
complaining about, it's worth fixing in the code. (And if it's not
worth fixing, it's not worth mentioning.) Second, having the compiler
generate warnings encourages the implementation to warn about weak
cases that can make compilation noisy, masking real errors that should
be fixed.
It's easy to address the situation, though. Use the blank identifier
to let unused things persist while you're developing.
import "unused"
// This declaration marks the import as used by referencing an
// item from the package.
var _ = unused.Item // TODO: Delete before committing!
func main() {
debugData := debug.Profile()
_ = debugData // Used only during debugging.
....
}
One solution for unused imports is to use goimports, which is a fork of gofmt. It automatically adds missing imports and removes unused ones (in addition to formatting your code).
http://godoc.org/code.google.com/p/go.tools/cmd/goimports
I've configured my editor to automatically run goimports whenever I save my code. I can't imagine writing go code without it now.
From what I just read, (wikipedia)
"Go's syntax includes changes from C aimed at keeping code concise and readable."
The word "concise" is very important to the compiler. I have found out
that the syntax enforced by the compiler is no longer "\n" or whitespace
agnostic. And there are no "warning" type errors.
There are good things about Go. There are some not so good things. The
attitude of no warnings is a bit extreme, especially when developing or testing
a new package. It seems that partial development is not acceptable. Warnings are not acceptable. It is either the production version or the highway. This is a very dualistic point of view. I wonder if evolution would have resulted in "life", if that had been the constraints on nature.
I can only hope that things will change. Death seems to be very beneficial at times.
I have tried Go, and I am disappointed. At my age I don't think I will return.

Where to find a full list of gcc warnings and errors?

Sometimes I need to use a gcc for cross-platform work, and sometimes gcc really amuses me with its warnings. For example:
#pragma once in a main file
This is very informative warning, but I really don't know what a 'main file' IS in terminology of gcc and WHY it must not contain #pragma once :). So, does any documentation exist that covers all gcc warnings and errors (mostly warnings, errors are trivial) with some comments on them?
The objective of '#pragma once' is to prevent a header from being reincluded. If you have it in a source file (usually a '.c' file), you won't be reading that twice (normally - I do know of a source file that reincludes itself [and I don't like it]; it does not use or want #pragma once, though!). So, a 'main file' in this context is one listed on the command line, for instance, rather than a header.
As to the subject matter of the question - the GCC manual does not seem to have a comprehensive list. I don't know whether there actually is one.

Resources