Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't I get 'Multiple Definitions' of enum in C?

Tags:

c

enums

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 enums different from the one visible when you have global variables or structs with the same name in different files?

like image 249
Paz Avatar asked Jan 27 '14 19:01

Paz


People also ask

Can enum have two same values?

Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

What is multiple definition error in C?

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.

Can we have enum containing enum with same constant?

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.

Is enum better than define?

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).


2 Answers

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.

like image 190
DAhrens Avatar answered Nov 16 '22 04:11

DAhrens


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.

like image 30
Jens Gustedt Avatar answered Nov 16 '22 04:11

Jens Gustedt