I'm working on embedded system project, and I don't know why I noticed this now, but if I define a variable twice the compiler doesn't give me any warning nor an error, which is very weird because I can accidently use the same name as another macro in the library which can easily send me to hell.
So what is the best practice to avoid, after thinking of it the only way is to test every name using #ifndef condition, but it the code will be very long and hard to read.
#define a 50 //defined in another library
#ifndef a // I check if 'a' already defined
#define a 10 // if not I can use that name
#endif
Think about doing this with hundred of macros, there must a better way which is directly related to the compiler.
CodePudding user response:
A compiler that conforms to the C standard must produce a diagnostic message if an identifier is redefined with different replacement text because the constraints section for macro replacement says, in C 2018 6.10.3 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…
If your compiler is not giving you such a warning, you should check for switches that improve its conformance to the C standard or that increase the warnings it produces. If there is no such switch, you should complain to the publisher of the compiler.
One way a failure to warn may arise is that some compilers have features for suppressing diagnostic messages while processing system headers. This is a reasonable behavior because system headers often need to do non-standard things that should be warned about (depending on circumstances) in user code but that may be considered intentional and proper design in system headers. However, it means that if you define a macro and then include a system header that also defines it (and differently), then the warning messages that would occur while processing the system header might be suppressed. To avoid that, include all system headers first, before you have any macro definitions.
For example, using GCC 12.2, this source code gets no warning:
#define EOF 4
#include <stdio.h>
but swapping the lines produces:
warning: "EOF" redefined
CodePudding user response:
it's not a big problem as you think , this is just a way is for safety purposes and not defining a micro twice but it's not a big deal because if you #define
macro twice the compiler will give you a warning telling you that there is a redefinition of macro like in the image below :
, but you can force to delete the previous definition of the macro using #undef
<the_name_of_macro> , also there are naming conventions your macros like : don't use _ at the start of your macro names because the macros beginning with underscore are C libraries specific , also it's more convenient to make your macro names all in capitals in order not to have a conflict with being misunderstood to be a variable not a macro and so on.
CodePudding user response:
There are at least these measures you should take:
- Raise the warning level of your compiler to the maximum.
- Apply a "no warnings, no errors" policy for your builds.
- Let the compiler look at warnings as errors. For GCC, this is the option
-Werror
.
CodePudding user response:
what is the best practice
- use upper case for macros representing constants
- do not use macros
- limit scope of everything
- use unique names, typically with module prefix followed by
_
, like#define LIB1_VALUE something
.
because I can accidently use the same name as another macro
Which suggests that your identifiers names are not unique enough. You should consider refactoring your code so that all identifiers are unique or limiting the scope of identifiers.
Think about doing this with hundred of macros
Writing a program to generate such source code should be trivial, a map with a loop with 3 lines to print. Code generation is often used with C programs, you can use M4, Jinja2 or even PHP as a better preprocessor.