When I compile my c project with make command, there is the error
Error: #47-D: incompatible redefinition of macro "MACRO_NAME"
It looks like MACRO_NAME is already defined in one of the header files, but I want to redefine or hardcode new value for MACRO_NAME.
How to remove this error?
There is no clean way to define this macro so that it realiably and predictably is not used in the meaning of one of the definitions, when the other one is meant.
If you use a mechanism with undef, then you run the risk to undefine the other meaning, define it to your meaning and then end up with code which expects the other meaning seeing and using your meaning.
The only way to achieve reliability and predictability is to make sure that code which expects one meaning does not include (neither directly nor indirectly) the header which defines the other meaning.
You can do so by
a) defining in a way that neither definition can be done when the other one is already defined. To do so, in both cases
#ifdef MACRO_NAME
#error Separation of the two meanings of MACRO_NAME failed!
/* the other definition of MACRO_NAME is alreay visible */
#endif
#define MACRO_NAME MyMeaning
b) make sure that no code includes both definitions
Actually a) is only a technical help to make sure b). If you say that you will not ever include both definitions into one code file, then you have no problem. In that case, you do not get the #error from a). In that case you do not have a problem with using the wrong definition. Good. How do you know? How can you be sure that you do not have the problem, even if you change code, even if your colleague changes code? Use a), then you will be clearly told when you get caught by the redefinition trap. If you use #undef instead, then you have not prevented the problem, just hidden it and made it harder to debug.
c) in the case that you can only influence one of the two definitions, i.e. the other one is by another supplier, the best way is to change the name of your own definition. Whatever effort that causes in your code, it will be less than getting caught be unintended redefinition problems.
d) in the case that you cannot influence any of the two definitions (which is of course NOT the case you are asking about) you have to separate the code files into two groups, those who use one definition and not the other and the group which uses the other definition and only that one.
Use #undef to redefine MACRO in the header file when it is needed
#ifdef MACRO_NAME
#undef MACRO_NAME
#endif
#define MACRO_NAME 100
Related
I was reading the C Preprocessor guide page on gnu.org on computed includes which has the following explanation:
2.6 Computed Includes
Sometimes it is necessary to select one of several different header
files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of
conditionals,
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3 …
#endif
That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a computed
include. Instead of writing a header name as the direct argument of
‘#include’, you simply put a macro name there instead:
#define SYSTEM_H "system_1.h"
…
#include SYSTEM_H
This doesn't make sense to me. The first code snippet allows for optionality based on which system type you encounter by using branching if elifs. The second seems to have no optionality as a macro is used to define a particular system type and then the macro is placed into the include statement without any code that would imply its definition can be changed. Yet, the text implies these are equivalent and that the second is a shorthand for the first. Can anyone explain how the optionality of the first code snippet exists in the second? I also don't know what code is implied to be contained in the "..." in the second code snippet.
There's some other places in the code or build system that define or don't define the macros that are being tested in the conditionals. What's suggested is that instead of those places defining lots of different SYSTEM_1, SYSTEM_2, etc. macros, they'll just define SYSTEM_H to the value that's desired.
Most likely this won't actually be in an explicit #define, instead of will be in a compiler option, e.g.
gcc -DSYSTEM_H='"system_1.h"' ...
And this will most likely actually come from a setting in a makefile or other configuration file.
Reading a chapter on the preprocessor, it stated that redefinition of macros is allowed only if the redefinition matches the previous definition, i.e:
#define FOO 0
#define BAR 1+1
#define FOO 0 /* ok. */
#define BAR 1 + 1 /* not ok */
I'm baffled by this.
Granted that this behavior is actually correct (the book might be wrong, of course), my question is: Why allow this? I can't think of any legitimate use-cases where this might be used (granted I don't have the experience), is there a rational behind it?
The idea is to make preprocessor to actively watch repetitive definitions and ensure that they remain identical.
The rationale behind this rule is actually mentioned in the Rationale to C99 standard
The Committee desired to disallow “pernicious redefinitions” such as
(in header1.h)
#define NBUFS 10
(in header2.h)
#define NBUFS 12
which are clearly invitations to serious bugs in a program. There remained, however, the question of “benign redefinitions,” such as
(in header1.h)
#define NULL_DEV /* the first time */ 0
(in header2.h)
#define NULL_DEV /* the second time */ 0
The C89 Committee concluded that safe programming practice is better served by allowing benign redefinition where the definitions are the same. This allows independent headers to specify their understanding of the proper value for a symbol of interest to each, with diagnostics generated only if the definitions differ.
Basically, the idea is to deliberately catch and expose situations when two definitions exist and they are different. If users were always forced to anticipate and #undef the previous definition before defining their own, they would quietly override what was not intended to be overridden, without a way to ensure consistency.
By deliberately supplying an extra identical definition you effectively introduce an extra level of protection: if someone modifies the previous definition, the preprocessor will immediately catch and report the resulting mismatch.
In other words by defining
#define A 42
in your code you are not only defining A as 42, you are also telling the preprocessor that you want to ensure that everyone else (in this translation unit) shares the same idea of what A should be.
Your book is strictly correct but perhaps fails to point out - or you might overlooked it -
that you may redefine a previously defined preprocessor with no diagnostic provided
that you undefine it before you redefine it. E.g:
#define FOO 0
#define BAR 1+1
#define FOO 0 /* ok. */
#undef BAR
#define BAR 1 + 1 /* ok */
If you attempt to redefine a macro while it is defined there's a high probability
you're committing a blunder and would be grateful for the preprocessor to
draw that to your attention.
When you define a macro in a file that inhabits a large, complex
product codebase - which perhaps has multiple, intertwined build-configurations
controlled by macros that are ultimately defined outside the codebase,
in the build system - then it may be beyond your unaided wits to know that
your definition will never, disastrously, contradict a prior definition in building any
configuration. You'd want to know that, and the preprocessor will tell you.
On the other hand, there are circumstances where you want say: FOO may or
may not have got a prior definition from somewhere at the point where my
file is compiled. Regardless, I want it to have my definition now.
I know what I'm doing and on my head be it. The preprocessor lets you assume that
responsibility as in:
foo.c
#include <bar.h>
...
#undef FOO // I don't care what it previously might have been.
#define FOO what I want here
and keeps quiet.
In that light, the question of why the preprocessor does not complain of
a macro redefinition that doesn't differ from the last one is probably
dispelled. Identical redefinitions are harmless. Useless, yes, but not
necessarily implying that you, or anyone, has repeated themselves. Library
header files libfoo.h and libbar.h might both be included in baz.c and
each of them might contain.
#define MAX_HANDLES 255
which the preprocessor will see twice. But it's harmless, so why complain?
To avoid impossible situation one could reduce the problem to two cases.
Case 1
The first (simplest) case is situation where the preprocessor has a chance to detect it, that is there's a preprocessor directive that depends on a macro being predefined (that is defined before the first line of input) or not. For example:
#ifdef FOO
#define BAR 42
#else
#define BAR 43
#endif
depends on FOO being predefined or not. However the file
#undef FOO
#ifdef FOO
#define BAR 42
#endif
does not. A harder case would be to detect if the dependency actually does matter, which it doesn't in the above cases (as neither FOO or BAR affects the output).
Case 2
The second (harder) case is where successful compilation depends on predefined macros:
INLINE int fubar(void) {
return 42;
}
which is perfectly fine as far as the preprocessor is concerned whether or not ENTRY_POINT is predefined, but unless INLINE is carefully defined that code won't compile. Similarily we could in this case it might be possible to exclude cases where the output isn't affected, but I can't find an example of that. The complication here is that in the example:
int fubar(void) {
return 42;
}
the fubar being predefined can alter the successful compilation of this, so one would probably need to restrict it to cases where a symbol need to be predefined in order to compile successfully.
I guess such a tool would be something similar to a preprocessor (and C parser in the second case). The question is if there is such a tool? Or is there a tool that only handles the first case? Or none at all?
In C everything can be (re)defined, so there is no way to know in advance what is intended to be (re)defined. Usually some naming conventions helps us to figure out what is meant to be a macro (like upper-case). Therefore it is not possible to have such tool. Of course if you assume that the compilation errors are caused by missing macro definitions then you can use them to analyze what is missing.
I found below macro defined in two header files of one of third party library
# define RATES_BALANCE_SCALER 1000000
To date no error comes but as I change the value of that macro in one file then following error started
error: "RATES_BALANCE_SCALER" redefined [-Werror]
Note: In compilation have set warning as error.
so can you please confirm my below understanding for compiler right or wrong?
MACRO replacement done at preprocessing time so when pre processor
find same name macro with different value then it will replace macro
value with later added header file and also generate error/warning
right?
Now when MACRO name and value both are same then compiler will not
generate any error/warning and replacement done by macro of later
added header file right? If right then why in this situation
compiler not generating warning or error?
They have the same name, so it is the same macro you're changing. But it is present in two files. As long as the value is the same there is no problem, but when you change the value the compiler can't figure out which one is the "right" one. This causes a conflict. Try not to define a value in more than one file. But if necessary put
#ifndef RATES_BALANCE_SCALER
#define RATES_BALANCE_SCALER 1000000
#endif
so that, if the value is already defined, it will not be redefined.
edit: This will cause the value to not change, if the third party macro is defined first! If you need the value, name it something different
Just defining the same thing as two different ones should be a programming error. This is the reason that the compiler emits an error when you redefine it differently. The compiler has support to #undef it and redefine differently, but there's no consensus on what you may mean on redefining a macro substitution.
Good compilers should emit an error when redefining a macro as a different thing and a warning when doing it several times (to the same string) but, as there's much legacy code that simply redefines the same constant in several places to ensure you finnaly get the definition, normally the compiler gets silent on it.
I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
When I run the preprocessor over this project, it does include that file, but the preprocessor output does not have the struct definition (but does include enum's from that file).
Is there a method to figure out why some of a header file gets to the preprocessor output, and some does not?
TIA
(Also, this is not the only compile error, the port is half done but it should be at least getting past this part)
I usually just track back from the structure to find all the enclosing "#ifdef" and "#if" lines that the preprocessor will encounter and see which one is controlling the removal of the structure from the input stream into the compiler.
That generally works pretty quickly for all but the hairiest of header files (i.e., those with a great many nested conditional compile statements). For those, I generally have a look at the preprocessor output to identify the last line in the header file that made it to the compiler input stream.
Almost certainly the next line will be a conditional compile statement where you haven't met the condition for inclusion.
For example, if this is the header file, you would need to track back to see that _KERNEL should be defined in order to get the declaration and definition.
I'm afraid not; you will have to look for #ifdefs that surround your area of interest and track down why those symbols are not defined. If it's porting to Linux/UNIX and you are missing things from the standard headers, you might have not defined the right _XOPEN_SOURCE or _BSD_SOURCE in your Makefile or config.h .
The most likely reason is there's a #define somewhere around the definition. Since the corresponding symbol is not defined or defined to some other value the definition is not included even when the header itself is included. You'll have to inspect this manually.
Raymond Chen has a blog post about this.
You may find yourself in a twisty maze of #ifdefs. Or you may be wondering why your macros aren't working.
I have these lines in my header file:
#define MM_BUSY 0x0001
#define MM_IDLE 0x0002
but when I try to use them, I get errors.
sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier
Any idea why this is happening?
Solution: Use #error to track down the problem the same way you'd scatter printf around to track down a regular bug.
Source: Use the #error directive to check whether the compiler even sees you
I do not think that there is a better way beside checking the preprocessor output to know why one file is included or not. Here is the gcc's preprocessor's output format that may help you understand the preprocessor's ouput.
Also, another way you may have a try to compare the outputs between that you are porting and the existing one.
You said:
I have a rather large project I'm porting, and in one of the MANY headers I've included a file that contains a struct definition for pmc_mdep. (Prior in the file its just declared, but later its actually defined).
Trying to compile it gives me errors about that struct being an incomplete type (which I believe means that it's lacking a definition).
This error can occur if you try to embed a pmc_mdep into some other structure before you have defined a pmc_mdep fully. Note that you can embed pointers to incomplete types into structures, but not actual instances of the incomplete type.
You also discuss running the preprocessor over the file that should define the structure, and you see enums form the header, but not the structure definition. That suggests that maybe you have a stray comment that is removing the structure unintentionally, or perhaps you have the structure definition embedded between #ifdef XXX and #endif but XXX is not defined when you do the compilation. It could even be #if 0.
I'd run the C preprocessor on just the header that contains the structure definition to see what that produces; it will be shorter than trying to look at the output for the entire program (source file). If I couldn't spot the issue swiftly, I'd mark parts with something like stray enums to see which ones get through and which ones don't.