11

I have the following source code which interests me.

#include <stdio.h>
extern int foo;
int foo = 32;

int main()
{
printf("%d", foo);
}

This a perfectly normal piece of code, and when I compile it with

gcc -Wall -Wextra -pedantic foo.c

I get no warnings.

And it seems weird, because a variable is defined both as external, and also global in the same file. I'm quite sure that it's easy to the linker to find the reference for the external variable in the same file, but doesn't it look like a coding error? And if so, why doesn't the compiler warn about this?

5 Answers 5

15

There's nothing weird. You first made a declaration of a variable (you promised the compiler that it exist) and then you actually defined it. There's no problem in that.

Also, by default, all variables that aren't local to functions and aren't defined as static are extern.

Sign up to request clarification or add additional context in comments.

3 Comments

first declare then defined can also be seen in function definition like: void function(int n; char d[n], int n); Am I correct ?
@GrijeshChauhan Correct. This is the mechanism that allows creation of programs out of smaller separately compiled parts (object files and libraries). Code and data may be scattered across a number of files.
I'm so grateful you said that "all variables that aren't local to functions and aren't defined as static are extern". I had assumed the opposite and it was killing me to figure out how to make a variable label defined in C visible to the assembler.
8

You seem to misunderstand what extern does. extern simply makes your declaration just a declaration instead of a definition.

int i; //definition of i
extern int i; //declaration of i

It is perfectly normal to have multiple declarations of the same variable, but only one definition should be present in the whole program. Compare this with a function

void f(void); //declaration
void f(void) //definition(and redeclaration)
{
} //definition

In order to use a variable or function, you only need its declaration. Its definition may appear anywhere in the program (the linker will find it). Anywhere can be the same file, another file, or even an external library.

Comments

7

And it's seems weired, because a variable is defined both as external, and also global in the same file.

extern int foo;

says: it declares without defining an object of type int named foo.

 int foo = 32;

it declares and defines an object of type int named foo with external linkage.

There is no contradiction and it is valid C code.

13 Comments

But if foo was actually declared ( as promised by extern ) in some other file, the code int foo = 32; would not be correct.
@Armin: foo can be declared as many times and in as many files as you like (with or without extern), but there cannot be more than one initialisation.
@teppic not without extern. At the end of a translation unit, the tentative(s) definition(s) will become a real definition. And it is undefined behavior to have multiple definitions of external objects with the same name.
@ouah - if you have int foo; in one file and int foo; in another, it's perfectly fine.
@teppic it is undefined behavior. Both tentative definitions will become real definitions at the end of their respective translation unit. And C99 says in 6.9p5 "If an identifier declared with external linkage is used in an expression [...], somewhere in the entire program there shall be exactly one extern one external definition for the identifier; otherwise, there shall be no more than one."
|
2

The difference is that the former is a declaration -> extern declares a variable and says it will be available somewhere around. You can have as many declarations as you want and the latter is a definition which must be there exactly once.
So there should be no warning and no error.

Comments

1

extern is a way to provide visibility to a variable that is defined elsewhere...

extern is like a promise...

in example.h

extern int g;// promises that this will be in the object code to anything that includes example.h

example. c

int g;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.