Let's say I have three files:
//m.h
const int RED = 1;
//m.h ends here
//f1.c
#include "m.h"
//f1.c ends here
//f2.c
#include "m.h"
int main() {return 0;}
//f2.c ends here
Compiling each one separately will work, but gcc -Wall f1.o f2.o -o prog
will produce:
multiple definition of 'RED'
Now if I replace the const with:
//m.h
enum {RED=1} colors;
//m.h ends here
I'll be able to compile prog
and use RED
as a const and won't get any multiple definition
error.
Why is the behavior with enum
s different from the one visible when you have global variables or structs with the same name in different files?
Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.
If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.
The values assigned to the enum names must be integral constant, i.e., it should not be of other types such string, float, etc. All the enum names must be unique in their scope, i.e., if we define two enum having same scope, then these two enums should have different enum names otherwise compiler will throw an error.
enum offers you scoping and automatic value assignment, but does not give any control over the constant type (always signed int ). #define ignores scoping, but allows you to use better typing facilities: lets you choose the constant type (either by using suffixes or by including an explicit cast into the definition).
An enumeration will not create a value in memory, which means there is no address added to the symbol table when linking.
A const variable will have an address in the compiled object, with a symbol name. When you try to link the two object files together, they each have the same symbol name "RED" pointing to different addresses, which is what causes your conflict.
Enumeration constants are not objects, they have only a value but no allocation inside the executable. So in your second example, RED
is just a definition of a value in each of the files. On the other hand color
is not what you think. It is a "tentative definition" of an object named color
. If you don't use it, it will not be allocated and everything seems fine. But it only seems so.
In your first example you have a const
-qualified object named RED
in each of the files. Since it is initialized this is a definition and the symbol is generated in each of the .o
files. Thus the complaint by the linker.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With