简体   繁体   中英

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?

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;"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM