This question already has an answer here:
-
#define many times without #undef,is it legal?
4 answers
-
What happens when a C preprocessor macro is defined twice?
3 answers
I want to know the severity of the warning that my compiler is throwing for the "macro MACRO_NAME redefined". It is redefined in the header file without undef directive like below:
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
What value does MACRO_NAME take throughout the program? Does it depend on the compiler? Is #undef mandatory here?
Well the second macro #define MACRO_NAME 8192
is taken into account . Anyhow it is a bad practiced because this can cause huge confusion when the new developer reads whole code written by you .
Usually it may happen that the same macro defined with different values in different header files , at that time it depends in what order you include these two header file . See in this case it may be easy for you but it is highly confusing when the new developer takes over your code.
Generally, treat all warnings as errors. Then you don't have to worry about what value the macro would have.(taken from comment above)
I will not recommend practice to redefine macro without undef
Usually you get this warning, and should use always a #undef as such a redifinition is invalid according to the C89 standard:
Well a beautiful example has been presented:
int a;
#define VAL 100
a=VAL; // a is 100 here
#define VAL 200
a=VAL; // a is 200 here
You can see the problem :)
If it compiles, then it overwrites the first macro with the value of the second.
#include <stdio.h>
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
int main()
{
printf("%d", MACRO_NAME);
return 0;
}
Output: 8192
Usually you get this warning, and should use always a #undef
as such a redifinition is invalid according to the C89 standard:
5:0: warning: "MACRO_NAME" redefined
3:0: note: this is the location of the previous definition
Verified by cpp.sh, onlinegdb.com and tutorialspoint.com.
What you are doing is invalid:
The C11 standard states this:
6.10.3 Macro replacement
Constraints
...
2 An identifier currently defined as an object-like macro shall not be redefined by another #define
preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical.
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
In the case of
#define MACRO_NAME 3.14
#define MACRO_NAME 8192
the replacement lists are not identical.
From C Standard#6.10.3p2 [emphasis mine]
2 An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
So, this is not valid as per the standard because the replacements (3.14
and 8192
) are not identical:
#define MACRO_NAME 3.14
/*other macro definition*/
#define MACRO_NAME 8192
You can use #undef
to make this code valid, like this:
#define MACRO_NAME 3.14
// the part of code using MACRO_NAME before #undef will expanded to 3.14
#undef MACRO_NAME
/*other macro definition*/
#define MACRO_NAME 8192
// after this the code using MACRO_NAME expanded to 8192
From C Standard#6.10.3.5p1 (Scope of macro definitions) [emphasis added]
1 A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit. Macro definitions have no significance after translation phase 4.
Additional:
From C Standard#6.10.3.5p8, the macro redefinition rules demonstration:
8 EXAMPLE 6 To demonstrate the redefinition rules, the following sequence is valid.
#define OBJ_LIKE (1-1)
#define OBJ_LIKE /* white space */ (1-1) /* other */
#define FUNC_LIKE(a) ( a )
#define FUNC_LIKE( a )( /* note the white space */ \
a /* other stuff on this line
*/ )
But the following redefinitions are invalid:
#define OBJ_LIKE (0) // different token sequence
#define OBJ_LIKE (1 - 1) // different white space
#define FUNC_LIKE(b) ( a ) // different parameter usage
#define FUNC_LIKE(b) ( b ) // different parameter spelling