cdeclarationsemanticsdefinition

Is `int x;` really just a declaration or an implicit definition too?


In C, if an object is declared. For instance, int x; as an automatic variable. Without initializing it with any value, is it still considered just a declaration and not definition?

Cause ChatGPT argues that when an object is declared, sometimes the compiler sets aside some memory associated with it (object). Therefore it is an implied definition. Please only answer if you are completely sure with the C semantics.


Solution

  • An object declared at file scope without an initializer as in this case is considered a tentative definition. Other identical declarations may appear, each of which is also a tentative definition.

    If no definition (i.e. one with an initializer) exists, then that tentative definition, along with any others that may appear, are considered a "full" definition for that identifier which is initialized to 0.

    This is spelled out in section 6.9.2p2 of the C standard:

    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.

    Such a declaration at block scope (i.e. in the body of a function) is a unique declaration for that object and is also a definition, as such a declaration sets aside storage for that object.

    All definitions are also declarations, as stated in section 6.7p5:

    A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:

    • for an object, causes storage to be reserved for that object;
    • for a function, includes the function body;
    • for an enumeration constant, is the (only) declaration of the identifier;
    • for a typedef name, is the first (or only) declaration of the identifier.