34

Why does this code work in C but not in C++?

int i = 5;
int i; // but if I write int i = 5; again I get error in C also

int main(){

  // using i
}
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
RON_L
  • 343
  • 2
  • 4

3 Answers3

50

Tentative definition is allowed in C but not in C++.

A tentative definition is any external data declaration that has no storage class specifier and no initializer.

C99 6.9.2/2

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 int i is a tentative definition. The C compiler will combine all of the tentative definitions into a single definition of i.

In C++ your code is ill-formed due to the One Definition Rule (Section 3.2/1 ISO C++)

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.


// but if I write int i = 5; again I get error in C also

Because in that case it no longer remains a tentative definition because of the initializer (5).


Just for the sake of information

J.5.11 Multiple external definitions

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).

Also check out this excellent post on external variables.

Community
  • 1
  • 1
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • @PrasoonSaurav: It's illegal in both C and C++ but C compilers implement a C extension for this to work. [See this](http://stackoverflow.com/a/6371156/183120) answer. – legends2k Mar 03 '14 at 12:07
  • 1
    @legends2k: It is not illegal in C. This is what the answer menetions "You can have multiple tentative definitions in a **single translation unit** but the effect is the same as having one non-tentative external definition (e.g. something like int a = 0;)." – Prasoon Saurav Mar 03 '14 at 15:46
  • @PrasoonSaurav: It's undefined behaviour; did you check the [comment by litb](http://stackoverflow.com/questions/1490693/tentative-definitions-in-c99-and-linking/1490777?noredirect=1#comment1344020_1490777)? – legends2k Mar 04 '14 at 00:50
  • @legends2k : No its not because the linkage do not disagree in this case. – Prasoon Saurav Mar 04 '14 at 06:06
11

Tha is called tentative definition. It's allowed only in C.

A tentative definition is any external data declaration that has no storage class specifier and no initializer. A tentative definition becomes a full definition if the end of the translation unit is reached and no definition has appeared with an initializer for the identifier. In this situation, the compiler reserves uninitialized space for the object defined.

The following statements show normal definitions and tentative definitions.

int i1 = 10;         /* definition, external linkage */
static int i2 = 20;  /* definition, internal linkage */
extern int i3 = 30;  /* definition, external linkage */
int i4;              /* tentative definition, external linkage */
static int i5;       /* tentative definition, internal linkage */

int i1;              /* valid tentative definition */
int i2;              /* not legal, linkage disagreement with previous */
int i3;              /* valid tentative definition */
int i4;              /* valid tentative definition */
int i5;              /* not legal, linkage disagreement with previous */

C++ does not support the concept of a tentative definition: an external data declaration without a storage class specifier is always a definition.

From here: Tentative Definitions

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

To understand tentative definition better, go through this

Community
  • 1
  • 1
Aditya Sehgal
  • 2,867
  • 3
  • 27
  • 37