Re: do { quit; } else { }

Liste des GroupesRevenir à cl c 
Sujet : Re: do { quit; } else { }
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.c
Date : 10. Apr 2025, 21:21:32
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250410122918.763@kylheku.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-04-10, David Brown <david.brown@hesbynett.no> wrote:
On 10/04/2025 17:41, Kaz Kylheku wrote:
On 2025-04-10, David Brown <david.brown@hesbynett.no> wrote:
So currently, I have no explanation for why you may write "static int
foo; extern int foo;" and have "foo" be internal linkage, while "extern
int foo; static int foo;" is not allowed.
 
What's also not allowed is "static int foo; int foo;" !
 
It's because "extern" means "refer to the existing file scope
declaration of the identifer if there is one propagating its
properties, including linkage; otherwise if it doesn't exist,
create an external linkage reference"
 
>
That's a summary of how "extern" works, but it results in a kind of
circular argument or tautology - it's just saying "extern means what it

I would never be so sloppy as to leave the two ends of any argument
of mine dangling, not neatly closed into a circle.

means".  It does not explain /why/ it works this way, or where the rules
came from, why C has use of a single keyword that works this way, and
why it is called "extern".

Where the rules came from is partially answered by the Rationale
for ANSI C, where it discusses the various linkage models for external
names that were in the wild.

The "ISO-ized" version of the Rationale is found here:

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n850.pdf

There is a 6.2.2 Linkages of Identifiers that has useful info,
starting with:

"The first declaration of an identifier, including implicit declarations
before C9X, must specify by the presence or absence of the keyword
static whether the identifier has internal or external linkage."

(OK, so right of the bat, that confirms that "extern" has no role
to play in establishing linkage other than that when it is present
in a first declaration, the static specifier must be absent, and the
absence of static is what is important. This is not a statement of
rationale, though, just status quo.)

The remaning text presents a brief summary of what existed before
the standard in terms of how internal linkage was implemented,
and several models for external linkage, given the names "Common",
"Relaxed Ref/Def", "Strict Ref/Def" and "Initialization":

  Common

    Every object declaration with external linkage, regardless of whether
    the keyword extern appears in the declaration, creates a definition
    of storage.  When all of the modules are combined together, each
    definition with the same name is located at the same address in
    memory. (The name is derived from common storage in Fortran.) This
    model was the intent of the original designer of C, Dennis Ritchie.

  Relaxed Ref/Def

    The appearance of the keyword extern in a declaration, regardless
    of whether it is used inside or outside of the scope of a
    function, indicates a pure reference (ref), which does not define
    storage. Somewhere in all of the translation units, at least one
    definition (def) of the object must exist. An external definition
    is indicated by an object declaration in file scope containing
    no storage class indication. A reference without a corresponding
    definition is an error. Some implementations also will not generate
    a reference for items which are declared with the extern keyword but
    are never used in the code. The UNIX operating system C compiler
    and linker implement this model, which is recognized as a common
    extension to the C language (see §K.5.11). UNIX C programs
    which take advantage of this model are standard conforming in
    their environment, but are not maximally portable (not strictly
    conforming).


  Strict Ref/Def

    This is the same as the relaxed ref/def model, save that only one
    definition is allowed.  Again, some implementations may decide not
    to put out references to items that are not used.  This is the model
    specified in K&R.

  Initialization

     This model requires an explicit initialization to define storage. All
     other declarations are references.


This is all relevant. The Common model for linkage was originally intended by
Ritchie. But then in K&R, the authors documented Strict Ref/Def.

Unix compiler and linkers used Relaxed Ref/Def: not every declaration
is a definition, but multiple definitions are allowed (as long as
they are the same).

Knowing that Unix uses Relaxed Ref/Def, they recommended something more
safer and more portable that will work off Unix: ensuring there is only
one definition of an external name that is used.

It looks like Ritchie's Common model informs the concept of a tentative
definition. When you have file scope declarations like "int x;" without extern,
that translation unit defines x.  You never use extern, other than in a lexical
scope in order to reach an existing external name.  If you have shared
variables, you put them in a header file and include it. That ensures that
everyone has the same definition. The definitions coming from different
compiled files get merged so there is one "int x" which sits at the same
address.

It looks like this Common model, related to Fortran, is probably
the best explanation of how we got here.

However, the Rationale says:

"The model adopted in the Standard is a combination of features of the strict
ref/def model and the initialization model."

It would be much simpler if we had "static int x;" to mean "declare x
with internal linkage and define it"

There are sometimes reasons why we need a static forward
declarations for an object (not to mention function). Example:

  static struct foo_operations;

  static void foo_create_similar(struct foo *old_foo)
  {
     struct foo *new_foo = malloc(sizeof *foo);
     ...
     // for whatever reason, this is not copied from old_foo
     new_foo->ops = &foo_operations;
     ...
     return foo;
  }

  static struct foo_operations = { ..., foo_clone, ... };

The function needs to refer to foo_operations for whatever reason, and the
initialisation of foo_operations need the function.

"extern int x;" to mean "declare x
to have extern linkage", and "int x;" to mean "declare x with external
linkage and define it".  That is how you use these in most circumstances
(and there are gcc warning flags to enforce it, for those that want to
do that).

So this describes the Strict Ref/Def model, like recommended in the K&R; but
not reflecting restrictions actually implemented in the wild!

C rarely makes things more complicated without a good reason.  You gave
the example of using "extern" for "unshadowing" an identifier (thank you
for that example!), but it doesn't strike me as sufficient
justification.  I had thought the reason for the way "extern" and
"static" interact was historical compatibility, but that does not appear
to be the case.

Dennis Ritchie's 1975 C reference manual already describes a local use
of extern:

  "In the extern case there must be an external definition (see below) for the
  given identifiers somewhere outside the function in which they are declared."

This is the only mention of the extern specifier that Ritchie gives,
indicating that it's not meant for file scope use (making external
definitions).

About external definitions (what the "see below" refers to above), he writes:

  "An external definition declares an identifier to have storage class extern
  and a specified type."

He does not specify that this requires the extern specifier!

Also, the static keyword exists in this manual but is again for local use,
not for file scope use.

IN an appendix about platform differences he writes:

  "The externanl definition "static int . . " is legal on GCOS, but gets a
  diagnostic on UNIX. (On GCOS it means an identifier global to the routines in
  the file but invisible to routines compiled separately.)

Wow! So static meaning "private to this file" was essentially a hack introduced
on GCOS that didn't owrk on Unix. I think that marks the first instance where
static was given an overloaded meaning: GCOS is the culprit.

Let us turn to the B language also, where extern was known as extrn.
(If that had not been changd, the authors would have two regrets: not putting
the 'e' in "creat" and in "extrn".)

The B user manual says:

  6.1 External Declaration

  The external declaration has the form:

     extrn name1 , name2 ... ;
 
  The external declaration specifies that each of the named variables
  is of the external storage class. The declaration must occur before
  the first use of each of the variables. Each of the variables must
  also be externally defined.

Again, in B, extrn are declarations that a name or names exist
externally, not definitions!

The following example occurs (abridged):

  main() {
      extrn putchar, n, v;
      auto i, c, col, a;

      i = col = 0;
      while(i<n)
          v[i++] = 1;
      while(col<2*n) {
          a = n+1 ;
          c = i = 0;
          while (i<n) {
              c =+ v[i] *10;
              v[i++]  = c%a;
              c =/ a--;
          }

          putchar(c+'0');
          if(!(++col%5))
              putchar(col%50?' ': '*n');
      }
      putchar('*n*n');
  }

  v[2000];
  n 2000;

For whatever reason, the extrn is put into the scope of main and not
at file scope. The subsequent definitions v[2000] and n 2000
do not mention any extrn; they are definitions, not declarations of
existence.

In B, extrn clearly means "trust me that the following names are
definied somewhere globally".

Lastly, a BNF grammar is given in the B manual. In this grammar
we have this:

  statement ::=
     ...
     extrn name {, name}0 ; statement

extrn isn't anything like storage class specifier at all, but
a statement keyword! And that is why it *must not* appear at
file scope.

The B language has no way to indicate that osmething exists
externally somewhere other than inside the body of a function.

The situations in which we must use extern at file scope today
are the result of the Strict Ref/Def model that came later.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
4 Apr 25 * do { quit; } else { }625Thiago Adams
4 Apr 25 +* Re: do { quit; } else { }2bart
4 Apr 25 i`- Re: do { quit; } else { }1Thiago Adams
4 Apr 25 +* Re: do { quit; } else { }11Kaz Kylheku
4 Apr 25 i+* Re: do { quit; } else { }3Thiago Adams
4 Apr 25 ii`* Re: do { quit; } else { }2Kaz Kylheku
4 Apr 25 ii `- Re: do { quit; } else { }1Chris M. Thomasson
4 Apr 25 i+* Re: do { quit; } else { }4Kaz Kylheku
4 Apr 25 ii+* Re: do { quit; } else { }2Thiago Adams
4 Apr 25 iii`- Re: do { quit; } else { }1Thiago Adams
8 Apr 25 ii`- Re: do { quit; } else { }1candycanearter07
5 Apr 25 i`* Re: do { quit; } else { }3Janis Papanagnou
5 Apr 25 i +- Re: do { quit; } else { }1Janis Papanagnou
6 Apr 25 i `- Re: do { quit; } else { }1Michael S
4 Apr 25 +* Re: do { quit; } else { }608Tim Rentsch
4 Apr 25 i`* Re: do { quit; } else { }607Thiago Adams
6 Apr 25 i +* Re: do { quit; } else { }600Tim Rentsch
6 Apr 25 i i+* Re: do { quit; } else { }550Michael S
6 Apr 25 i ii`* Re: do { quit; } else { }549Tim Rentsch
6 Apr 25 i ii `* Re: do { quit; } else { }548Michael S
7 Apr 25 i ii  `* Re: do { quit; } else { }547Tim Rentsch
7 Apr 25 i ii   `* Re: do { quit; } else { }546Michael S
7 Apr 25 i ii    +* Re: do { quit; } else { }542bart
8 Apr 25 i ii    i`* Re: do { quit; } else { }541David Brown
8 Apr 25 i ii    i `* Re: do { quit; } else { }540bart
8 Apr 25 i ii    i  +* Re: do { quit; } else { }535David Brown
8 Apr 25 i ii    i  i`* Re: do { quit; } else { }534bart
8 Apr 25 i ii    i  i +* Re: do { quit; } else { }78Tim Rentsch
8 Apr 25 i ii    i  i i`* Re: do { quit; } else { }77bart
8 Apr 25 i ii    i  i i +* Re: do { quit; } else { }74Tim Rentsch
8 Apr 25 i ii    i  i i i`* Re: do { quit; } else { }73bart
9 Apr 25 i ii    i  i i i `* Re: do { quit; } else { }72Tim Rentsch
9 Apr 25 i ii    i  i i i  `* Re: do { quit; } else { }71bart
9 Apr 25 i ii    i  i i i   +- Re: do { quit; } else { }1Chris M. Thomasson
9 Apr 25 i ii    i  i i i   +- Re: do { quit; } else { }1Chris M. Thomasson
9 Apr 25 i ii    i  i i i   `* Re: do { quit; } else { }68Tim Rentsch
10 Apr 25 i ii    i  i i i    +* Re: do { quit; } else { }63bart
10 Apr 25 i ii    i  i i i    i+* Re: do { quit; } else { }61Kaz Kylheku
10 Apr 25 i ii    i  i i i    ii+* Re: do { quit; } else { }2Michael S
10 Apr 25 i ii    i  i i i    iii`- Re: do { quit; } else { }1Kaz Kylheku
10 Apr 25 i ii    i  i i i    ii`* Re: do { quit; } else { }58bart
10 Apr 25 i ii    i  i i i    ii +* Re: do { quit; } else { }43Keith Thompson
10 Apr 25 i ii    i  i i i    ii i+* Re: do { quit; } else { }39bart
10 Apr 25 i ii    i  i i i    ii ii+* Re: Endless complaints [was Re: do { quit; } else { }]16bart
10 Apr 25 i ii    i  i i i    ii iii+* Re: Endless complaints [was Re: do { quit; } else { }]14Janis Papanagnou
11 Apr 25 i ii    i  i i i    ii iiii`* Re: Endless complaints [was Re: do { quit; } else { }]13bart
11 Apr 25 i ii    i  i i i    ii iiii +- Re: Endless complaints [was Re: do { quit; } else { }]1Keith Thompson
11 Apr 25 i ii    i  i i i    ii iiii +- Re: Endless complaints [was Re: do { quit; } else { }]1Kaz Kylheku
11 Apr 25 i ii    i  i i i    ii iiii `* Re: Endless complaints [was Re: do { quit; } else { }]10David Brown
11 Apr 25 i ii    i  i i i    ii iiii  `* Re: Endless complaints [was Re: do { quit; } else { }]9bart
11 Apr 25 i ii    i  i i i    ii iiii   +* Re: Endless complaints [was Re: do { quit; } else { }]5Michael S
11 Apr 25 i ii    i  i i i    ii iiii   i`* Re: Endless complaints [was Re: do { quit; } else { }]4bart
11 Apr 25 i ii    i  i i i    ii iiii   i `* Re: Endless complaints [was Re: do { quit; } else { }]3Michael S
11 Apr 25 i ii    i  i i i    ii iiii   i  +- Re: Endless complaints [was Re: do { quit; } else { }]1Janis Papanagnou
11 Apr 25 i ii    i  i i i    ii iiii   i  `- Re: Endless complaints [was Re: do { quit; } else { }]1bart
11 Apr 25 i ii    i  i i i    ii iiii   +- Re: Endless complaints [was Re: do { quit; } else { }]1David Brown
11 Apr 25 i ii    i  i i i    ii iiii   +- Re: Endless complaints1Tim Rentsch
11 Apr 25 i ii    i  i i i    ii iiii   `- Re: Endless complaints [was Re: do { quit; } else { }]1Keith Thompson
10 Apr 25 i ii    i  i i i    ii iii`- Re: Endless complaints [was Re: do { quit; } else { }]1Keith Thompson
10 Apr 25 i ii    i  i i i    ii ii`* Re: do { quit; } else { }22Keith Thompson
11 Apr 25 i ii    i  i i i    ii ii `* Re: do { quit; } else { }21bart
11 Apr 25 i ii    i  i i i    ii ii  `* Re: do { quit; } else { }20Keith Thompson
11 Apr 25 i ii    i  i i i    ii ii   `* Re: do { quit; } else { }19Michael S
11 Apr 25 i ii    i  i i i    ii ii    +- Re: do { quit; } else { }1David Brown
11 Apr 25 i ii    i  i i i    ii ii    +* Re: do { quit; } else { }16Kaz Kylheku
11 Apr 25 i ii    i  i i i    ii ii    i+* Re: do { quit; } else { }2bart
11 Apr 25 i ii    i  i i i    ii ii    ii`- Re: do { quit; } else { }1Keith Thompson
13 Apr 25 i ii    i  i i i    ii ii    i`* Re: do { quit; } else { }13Michael S
12 May 25 i ii    i  i i i    ii ii    i `* Re: do { quit; } else { }12Tim Rentsch
12 May 25 i ii    i  i i i    ii ii    i  `* Re: do { quit; } else { }11David Brown
12 May 25 i ii    i  i i i    ii ii    i   `* Re: do { quit; } else { }10Keith Thompson
13 May 25 i ii    i  i i i    ii ii    i    `* Re: do { quit; } else { }9David Brown
14 May 25 i ii    i  i i i    ii ii    i     `* Re: do { quit; } else { }8James Kuyper
14 May 25 i ii    i  i i i    ii ii    i      +* Re: do { quit; } else { }6Keith Thompson
14 May 25 i ii    i  i i i    ii ii    i      i+* Re: do { quit; } else { }4James Kuyper
14 May 25 i ii    i  i i i    ii ii    i      ii`* Re: do { quit; } else { }3David Brown
14 May 25 i ii    i  i i i    ii ii    i      ii +- Re: do { quit; } else { }1Kaz Kylheku
15 May 25 i ii    i  i i i    ii ii    i      ii `- Re: do { quit; } else { }1James Kuyper
14 May 25 i ii    i  i i i    ii ii    i      i`- Re: do { quit; } else { }1David Brown
14 May 25 i ii    i  i i i    ii ii    i      `- Re: do { quit; } else { }1Tim Rentsch
11 Apr 25 i ii    i  i i i    ii ii    `- Re: do { quit; } else { }1Keith Thompson
6 May 25 i ii    i  i i i    ii i`* Re: do { quit; } else { }3Tim Rentsch
6 May 25 i ii    i  i i i    ii i `* Re: do { quit; } else { }2Keith Thompson
6 May 25 i ii    i  i i i    ii i  `- Re: do { quit; } else { }1Tim Rentsch
10 Apr 25 i ii    i  i i i    ii `* Re: do { quit; } else { }14Kaz Kylheku
10 Apr 25 i ii    i  i i i    ii  +* Re: do { quit; } else { }11bart
10 Apr 25 i ii    i  i i i    ii  i+* Re: do { quit; } else { }2Kaz Kylheku
11 Apr 25 i ii    i  i i i    ii  ii`- Re: do { quit; } else { }1bart
11 Apr 25 i ii    i  i i i    ii  i+* Re: do { quit; } else { }6Tim Rentsch
11 Apr 25 i ii    i  i i i    ii  ii`* Re: do { quit; } else { }5Keith Thompson
11 Apr 25 i ii    i  i i i    ii  ii `* Re: do { quit; } else { }4Tim Rentsch
11 Apr 25 i ii    i  i i i    ii  ii  `* Re: do { quit; } else { }3Keith Thompson
11 Apr 25 i ii    i  i i i    ii  ii   +- Re: do { quit; } else { }1bart
5 May 25 i ii    i  i i i    ii  ii   `- Re: do { quit; } else { }1Tim Rentsch
11 Apr 25 i ii    i  i i i    ii  i+- Re: do { quit; } else { }1Keith Thompson
11 Apr 25 i ii    i  i i i    ii  i`- Re: do { quit; } else { }1Keith Thompson
10 Apr 25 i ii    i  i i i    ii  +- Re: do { quit; } else { }1bart
10 Apr 25 i ii    i  i i i    ii  `- Re: do { quit; } else { }1Kaz Kylheku
11 Apr 25 i ii    i  i i i    i`- Re: do { quit; } else { }1Tim Rentsch
9 May 25 i ii    i  i i i    `* Re: do { quit; } else { }4Bonita Montero
9 May 25 i ii    i  i i i     `* Re: do { quit; } else { }3Richard Heathfield
9 Apr 25 i ii    i  i i +- Re: do { quit; } else { }1Richard Damon
9 Apr 25 i ii    i  i i `- Re: do { quit; } else { }1David Brown
9 Apr 25 i ii    i  i `* Re: do { quit; } else { }455David Brown
8 Apr 25 i ii    i  +- Re: do { quit; } else { }1Tim Rentsch
9 Apr 25 i ii    i  `* Re: do { quit; } else { }3Ike Naar
8 Apr 25 i ii    `* Re: do { quit; } else { }3Tim Rentsch
6 Apr 25 i i`* Re: do { quit; } else { }49Michael S
7 May 25 i `* Re: do { quit; } else { }6Wuns Haerst
6 Apr 25 +- Re: do { quit; } else { }1Lawrence D'Oliveiro
6 Apr 25 +- Re: do { quit; } else { }1David Brown
18 Apr 25 `- Re: do { quit; } else { }1Mikko

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal