Ich habe untersucht, wann es möglich ist, Variablen zu mischen, die mit extern
, static
und keinem Speicherspezifizierer im globalen Gültigkeitsbereich deklariert sind. Die Ergebnisse haben mich ziemlich verwirrt.Deklarationen mit externem, statischem und keinem Speicherspezifizierer im globalen Gültigkeitsbereich
Das ist, was ich gefunden (jeder Absatz ist eine separate Übersetzungseinheit):
/* ok */
int x;
int x;
/* ok */
int f();
int f();
/* ok */
int x;
extern int x;
/* ok */
int f();
extern int f();
/* error: static declaration follows non-static declaration */
int x;
static int x;
/* ok (no warning) */
int f();
static int f();
/* ok */
extern int x;
int x;
/* ok */
extern int f();
int f();
/* ok */
extern int x;
extern int x;
/* ok */
extern int f();
extern int f();
/* error: static declaration follows non-static declaration */
extern int x;
static int x;
/* error: static declaration follows non-static declaration */
extern int f();
static int f();
/* error: non-static declaration follows static declaration */
static int x;
int x;
/* ok (no warning) */
static int f();
int f();
/* ok */
static int x;
extern int x;
/* ok */
static int f();
extern int f();
/* ok */
static int x;
static int x;
/* ok */
static int f();
static int f();
ich die gleichen genauen Ergebnisse mit gcc
bekommen und clang
aber ich kann ein Muster in nicht finden, was funktioniert und was nicht Arbeit.
Gibt es hier irgendeine Logik?
Was sagen die C-Standards zum Mischen globaler Deklarationen, die mit extern
, static
und keinem Speicherbezeichner deklariert wurden?
Es gibt keine so etwas wie _ "no linkage" _ WRT globale Variablen. Der Standard (6.2.2 5) ist dabei ziemlich klar: _ "Wenn die Deklaration eines Bezeichners für eine Funktion keinen Speicherklassenbezeichner hat, wird ihre Verknüpfung genau so bestimmt, als wäre sie mit dem Speicherklassenspezifizierer extern deklariert worden. Wenn die Deklaration eines Bezeichners für ein Objekt Dateibereich und keinen Speicherklassenbezeichner hat, ist seine Verknüpfung extern. "_ –
Anstatt C durch diesen testgesteuerten Ansatz zu lernen, sollten Sie sich vielleicht ein gutes Buch nehmen und darüber lesen. Und wenn Sie wirklich in der Spezifikation darüber wissen wollen, laden Sie einen Standardentwurf herunter (es ist kostenlos) und lesen Sie es selbst. Ab jetzt ist Ihre Frage einfach zu weit gefasst, IMO. – Downvoter
Es gibt keine statische Verknüpfung und "statische" sowie "extern" sind Speicherklasse Spezifizierer in erster Linie. Verbindungsspezifikation ist ein Nebenprodukt. – Olaf