bagwell
bagwell

Reputation: 33

Behavior of an uninitialized global variable in a header file

test.h

#ifndef TEST_H
#define TEST_H

int i;

int i = 1; // why no redefinition error issued?

#endif  /* TEST_H */

test.c

#include "test.h"

int main() {
  int x;
  int x = i; // obviously, a redefinition
  return 0;
}

I am really curious about the behavior of an uninitialized global variable in a header file. As far as I know, both "int i;" and "int i = 1" are effective definitions for i but in practice neither clang nor gcc will issue an error for this case. Can anybody explain the detail?

Upvotes: 1

Views: 289

Answers (1)

Alper
Alper

Reputation: 13220

It is tentative definition as explained here.

At the top level of a translation unit (that is, a source file with all the #includes after the preprocessor), every C program is a sequence of declarations, which declare functions and objects with external linkage. These declarations are known as external declarations because they appear outside of any function.

Tentative definitions

A tentative definition is an external declaration without an initializer, and either without a storage-class specifier or with the specifier static.

A tentative definition is a declaration that may or may not act as a definition. If an actual external definition is found earlier or later in the same translation unit, then the tentative definition just acts as a declaration.

int i1 = 1;     // definition, external linkage
int i1;         // tentative definition, acts as declaration because i1 is defined
extern int i1;  // declaration, refers to the earlier definition

extern int i2 = 3; // definition, external linkage
int i2;            // tentative definition, acts as declaration because i2 is defined
extern int i2;     // declaration, refers to the external linkage definition

If there are no definitions in the same translation unit, then the tentative definition acts as an actual definition with the initializer = 0 (or, for array types, = {0}).

int i3;        // tentative definition, external linkage
int i3;        // tentative definition, external linkage
extern int i3; // declaration, external linkage
// in this translation unit, i3 is defined as if by "int i3 = 0;"

Upvotes: 1

Related Questions