Jayesh
Jayesh

Reputation: 4903

Behaviour of global variable in C

If I declared array as a global like this:

#include <stdio.h>

char arr[];

int main()
{
    return 0;
}

The compiler generates a warning:

test.c:3:6: warning: array ‘arr’ assumed to have one element [enabled by default]
 char arr[];

But, If I declared array as a global and explicit provide extern keyword like this:

extern char arr[];

int main()
{
    return 0;
}

Then, it's compile fine without warning.

But, By default global variables are extern, then why does first case generated warning?

Upvotes: 2

Views: 221

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 149075

Beware there is a little confusion in your terms:

By default global variables are extern

Not exactly: global variable have external linkage unless they are declared static. In that latter case they have internal linkage.

External linkage means that the variable may be refered from a different translation unit (another source file) if it is declared extern there. The extern specifier declares that the variable should be defined elsewhere with external linkage.

That explains your problem:

char arr[];

is a tentative (incorrect here) definition of a character array with external linkage. As the size is not specified and cannot be deduced from an initializer, it cannot fully define the array. As it is not declared extern and as no complete definition exists in that translation unit, it is an incorrect definition.

extern char arr[];

on the other hand only declares arr to be a char array, which is assumed to be defined elsewhere, possibly in a different translation unit. The program will be ill formed with no diagnostic required if there is no definition.

But this is a perfectly correct program:

#include <stdio.h>

char arr[];  // tentative definition

int main()
{
    // can use arr here, except for sizeof(arr) which would be an error
    // because only a declaration (not a definition) has been seen to this point
    return 0;
}

char arr[] = "abcd";  // full definition: the size is deduced to be 5

The tentative definition is only seen as a forward declaration. As the definition exists in the translation unit the compiler is glad with it...

Upvotes: 4

unwind
unwind

Reputation: 399949

The first case needs to allocate memory at run-time for an array of unspecified length. This is "hard", which is why the compiler complains and cheats out by assuming a length of 1.

The second case only needs for someone else to provide a base address for an array, and it's that someone's problem to make sure there's memory allocated at the provided location.

Not entirely sure how the details land, but that's the basic difference between the two.

The C11 draft even has this as an explicit example:

extern int *x;
extern int y[];

The first declares x to be a pointer to int; the second declares y to be an array of int of unspecified size (an incomplete type), the storage for which is defined elsewhere.

Upvotes: 8

llllllllll
llllllllll

Reputation: 16424

When you write a

char arr[];

in global scope, your intention is to define an array with static lifetime. Thus you must specify how many elements it contains.

When you write

extern char arr[];

it's only a declaration, to tell compiler that an array named arr exists somewhere else, not defined here. Thus no size is required.

Upvotes: 5

Related Questions