Reputation: 24758
Why am I getting multiple definition error here? After all I am using i
in two separate files.
//file1.c
#include <stdio.h>
#include "foo.h"
int i=700;
int main() {
printf("in main i is %d\n", i);
foo();
}
//file2.c
#include <stdio.h>
int i =800;
void foo() {
printf("in foo i is %d\n", i);
}
Error:
$ gcc file1.c file2.c
/tmp/ccyRgnlM.o:(.data+0x0): multiple definition of `i'
/tmp/ccoTZsnQ.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
I was reading the GNU C reference Manual: http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Scope
and I quote from there: "Unless explicitly stated otherwise, declarations made at the top-level of a file (i.e., not within a function) are visible to the entire file, including from within functions, but are not visible outside of the file."
Upvotes: 0
Views: 209
Reputation: 320421
The statement about "visibility" you quoted is formally correct, but requires precise understanding. In particular, you have to understand the difference between declarations and definitions, as well as the difference between being "visible" for name lookup purposes or for linkage purposes.
The statement you quoted specifically talks about properties of declarations. Indeed, a declaration made at the top level of the file is only visible within that file. "Visible" in this case means "visible for name lookup purposes".
However, your declarations if i
are more than just declarations. They are definitions as well.
And since they are definitions, they also have to obey the rules that govern definitions, like "one-definition rule" of C language. The rule says that entities with external linkage (variables or functions) have to be defined once and only once in the entire program. For linkage purposes entities with external linkage are always visible to the entire program.
A file-level variable declared without storage class specifier acquires external linkage by default, i.e. it becomes a global variable. Such variable still needs to be redeclared in each file where you want to use it (to make it visible in that file). However, you are not allowed to redefine it in any other translation unit.
If you really want to have an independent variable i
in each translation unit, you have to make sure you declare it with internal linkage, i.e. with keyword static
.
Upvotes: 2
Reputation: 635
When you #include
a file, cpp (the C pre-processor) literally pastes the lines of that file in place of the #include
line, so when you think of it that way, it's obvious to see how i
has been defined twice.
To do what you intended, i.e., to create two separate file-scoped variables called i
(one for each source file), declare them static
--this will give them file scope, and get rid of the warning.
/* file1.c */
static int i = 700;
/* file2.c */
#include "file1.c"
static int i = 800;
Upvotes: 0
Reputation: 1
You are not only using but you are defining global variable i
in both file1.c
& file2.c
Notice that in C a variable declaration is not the same as a definition !
You have
int i=700;
and
int i=800;
What initialization of global location i
do you want? It cannot be both 700 & 800 and it cannot be defined twice.
The correct way would be to have a header file myheader.h
:
#ifndef HEADER_INCLUDED
#define HEADER_INCLUDED
extern int i;
void foo (void);
#endif
and add #include "myheader.h"
at start of each file1.c
and file2.c
to declare (not define) a global variable i
and define it in one single file (often the one containing main
, here file1.c
) :
// file1.c
#include <stdio.h>
#include "myheader.h"
int i=750;
int main() {
printf("in main i is %d\n", i);
foo();
}
You might want to have two different variables i
(but avoid doing that, this is bad practice for readability reasons), then declare static int i;
in each file?.c
and don't mention i
in the header file.
At last, as a beginner in C using GCC, always compile with all warnings and debug info ie with at least gcc -std=c99 -Wall -g
(and improve your code till no warning happens). Learn how to use make
(the builder) and gdb
(the debugger).
Upvotes: 2
Reputation: 9340
Fro global symbols, C uses flat namespace. That means, there cannot be the same global symbol in different files since their name will be the same and thus, multiple definition linking error occurs. The solution is to either rename so they're all unique, or limit the scope by prefixing the symbol with static
, so the symbol is known locally to the file (better: translation unit) only.
P.S.: Symbol means identifier, it can be variable, function, type, etc.
Upvotes: 1
Reputation: 500307
You have two global variables called i
, and they clash with each other.
Since they are two distinct variables, declared them as static
. This will reduce their scope to the corresponding translation unit (i.e. source file).
For example:
static int i = 700;
Upvotes: 4