user9623401
user9623401

Reputation:

How Linkers Resolve Multiply Defined Global Symbols in C

My Textbook says that:

"Functions and initialized global variables get strong symbols. Uninitialized global variables get weak symbols.Given a strong symbol and multiple weak symbols, choose the strong symbol"

So I create two files to see:

file1.c:

int number;

int main(int argc, char *argv[]) 
{
    printf("%d",number);
    return 0;
}

file2.c (just one line):

int number = 2018;

and I ran gcc -Wall -o program file1.c file2.c and the output is 0, which I can understand before I study linker ('number' in file1.c has been initialized to 0), but after I study how linker works, I start to wonder why the output is not 2018, since the 'number' in file2 is strong symbol(initialized global variable) and the 'number' in file1 is weak symbol, so the linker will choose the strong one whose value is 2018, so why the linker choose the weak symbol?

Upvotes: 3

Views: 725

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 222526

The int number; in file1.c is not uninitialized. Note that it is declared at file scope, it is declared without an initializer, and it is declared without a storage-class specifier (particularly no extern or static). Then C 2018 6.9.2 2 says:

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

So, for purposes of initialization, int number; in file1.c is the same as int number = 0;. It is initialized.

An issue with the text you quote is that it is describing the linker using terminology for that linker, and this is different terminology than the the C standard uses. The C standard does not have any “global” variables or “strong” or “weak” symbols.

Upvotes: 4

Chris Turner
Chris Turner

Reputation: 8142

The number in file2.c is global, but still locally scoped just to that file. If you want file1.c to use number from file2.c you need to mark it as extern like this:

extern int number;

int main(int argc, char *argv[]) 
{
    printf("%d",number);
    return 0;
}

Upvotes: 0

Related Questions