🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #4162

Re: Tentative definitions

#4162
From: Clive D.W. Feather
Date: Tue, 03 Oct 1995 05:21
109 lines
5169 bytes
In article <44pdr1$378@news.tuwien.ac.at> ,
Konrad Schwarz <schwarz@mips.complang.tuwien.ac.at>  wrote:
> An older version of Microsoft C does not make ``i'' have external linkage
> in the following code:
> 
> extern int i;
> int i;

It does not conform to the Standard.

> Section 6.1.2.2, 4th paragraph:
> ``If the declaration of an identifier for an object or a fuction contains
> the storage-class specifier extern, the identifier has the same linkage as any
> visible declaration of the identifier with file scope.  If there is no visible
> declaration with file scope and no storage-class specifier, its linkage is
> external.''
> 
> What does visible declaration mean?

It means visible according to the scope rules. Assuming the above text
is not within a block, then at the first line there is no visible
declaration of i at all, so the linkage is external. At the second line
the first line is visible, so the linkage remains external.

> Does imply that file scope declarations of objects without external
> definitions have internal linkage?

> ``A declaration of an identifier for an object that has file scope without an
> initializer, and without a storage-class specifier or [...], 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.''
>
> Does imply that file scope declarations of objects without external
> definitions have internal linkage?

No. This is something else entirely: does the object have a definition
in this translation unit.

Remember:
* Declarations indicate what the type of the identifier is.
* Definitions indicate whether storage should be reserved. All definitions
  are declarations, but not vice versa.
* Linkage indicates when two declarations or definitions refer to the
  same object.

If there is a declaration of an object with external linkage, then there
must be a definition of it either here or in another translation unit.

Here's some examples for an article I wrote for CUJ:

static int var_a = 1;      /* Internal linkage, definition */
static int var_a;          /* Remains internal linkage */
extern int var_a;          /* Remains internal linkage */
int var_a;                 /* Error - var_a has internal linkage */
static int var_a = 1;      /* Error - more than one definition */

static int var_b;          /* Internal linkage, tentative definition */
extern int var_b = 1;      /* Remains internal linkage, definition overrides
                              tentative definition */

int var_c = 1;             /* External linkage, definition */
extern int var_c;          /* Remains external linkage */
int var_c;                 /* Remains external linkage */
static int var_c;          /* Error - var_c has external linkage */
static int var_c = 1;      /* Error - more than one definition */

extern int var_d = 1;      /* External linkage, definition */

static int var_e;          /* Internal linkage, tentative definition */
int var_e = 1;             /* Error - var_d has internal linkage */

static int var_f;          /* Internal linkage, tentative definition */
int var_g;                 /* External linkage, tentative definition */
extern int var_h;          /* External linkage */
extern int var_f;          /* Remains internal linkage */
static int var_f;          /* Remains internal linkage, another tentative
                              definition */

int main (void)
{
    extern int var_i;      /* External linkage */
    extern int var_j;      /* External linkage */
    extern int var_k;      /* External linkage */

    auto int var_f, var_g; /* Auto declarations hide the previous ones */

    {
        extern int var_f;  /* Error - hidden var_f has internal linkage */
        extern int var_g;  /* Remains external linkage */

        /* var_g here refers to the external linkage variable once more */
    }

    /* var_g here refers to the auto variable */
    return 0;
}

int var_i;                 /* Remains external linkage, tentative definition */
extern int var_j;          /* Remains external linkage */
static int var_k;          /* Error - var_k has external linkage */

-- 
Clive D.W. Feather                       | If you lie to the compiler,
clive@demon.net        (work, preferred) | it will get its revenge.
clive@stdc.demon.co.uk (home)            |   - Henry Spencer
Technical Details
Message-ID: <DFuxK4.62z@stdc.demon.co.uk>
Path: arc1-ca.pugleaf.net!stdc.demon.co.uk!clive
References: <44pdr1$378@news.tuwien.ac.at>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!stdc.demon.co.uk!clive
From: clive@stdc.demon.co.uk (Clive D.W. Feather)
Newsgroups: comp.std.c
Subject: Re: Tentative definitions
Date: Tue, 3 Oct 1995 05:21:38 GMT
Organization: Demon Internet Limited (personal account)
Message-ID: <DFuxK4.62z@stdc.demon.co.uk>
References: <44pdr1$378@news.tuwien.ac.at> 
Reply-To: clive@demon.net
Keywords: external linkage
X-NNTP-Posting-Host: stdc.demon.co.uk