Liste des Groupes | Revenir à cl c |
On 2025-04-10, David Brown <david.brown@hesbynett.no> wrote::-)On 10/04/2025 17:41, Kaz Kylheku wrote:I would never be so sloppy as to leave the two ends of any argumentOn 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
of mine dangling, not neatly closed into a circle.
Thank you for posting that. I'm snipping it for space here, but I appreciate the historical explanation.means". It does not explain /why/ it works this way, or where the rulesWhere the rules came from is partially answered by the Rationale
came from, why C has use of a single keyword that works this way, and
why it is called "extern".
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
Sure. I was simplifying things with just "int" objects. Static forward declarations are essential in recursive structures and recursive functions. (I was also simplifying by ignoring initialisation.)It would be much simpler if we had "static int x;" to mean "declare xThere are sometimes reasons why we need a static forward
with internal linkage and define it"
declarations for an object (not to mention function). Example:
static struct foo_operations;I think it is fair to say that the early C reference manuals were not as formal, rigorous and tightly specified as later ISO standards.
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 xSo this describes the Strict Ref/Def model, like recommended in the K&R; but
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).
not reflecting restrictions actually implemented in the wild!
C rarely makes things more complicated without a good reason. You gaveDennis Ritchie's 1975 C reference manual already describes a local use
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.
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!
Les messages affichés proviennent d'usenet.