Nachschlagen und Namensräume
Wenn ein Bezeichner in einem C-Programm angetroffen wird, wird eine Suche durchgeführt, um die Deklaration zu finden, die diesen Bezeichner eingeführt hat und die aktuell im Geltungsbereich liegt. C erlaubt, dass mehr als eine Deklaration für denselben Bezeichner gleichzeitig im Geltungsbereich liegt, wenn diese Bezeichner zu verschiedenen Kategorien gehören, die als Namensräume bezeichnet werden.
|
4) Globaler Attribut-Namensraum: Attribut-Token, die vom Standard oder von implementierungsdefinierten Attribut-Präfixen definiert wurden.
5) Nicht-Standard-Attributnamen: Attributnamen, die Attribut-Präfixen folgen. Jedes Attribut-Präfix hat einen separaten Namensraum für die implementierungsdefinierten Attribute, die es einführt.
|
(seit C23) |
Zum Zeitpunkt der Suche wird der Namensraum eines Bezeichners durch die Art und Weise bestimmt, wie er verwendet wird.
|
4) Ein Bezeichner, der direkt in einem Attributspezifizierer ([[...]]) erscheint, wird im globalen Attribut-Namensraum gesucht.
5) Ein Bezeichner, der auf das Token :: nach einem Attribut-Präfix folgt, wird im Namensraum gesucht, der durch das Attribut-Präfix eingeführt wird.
|
(seit C23) |
Inhalt |
[bearbeiten] Hinweise
Die Namen von Makros sind keinem Namensraum zugeordnet, da sie vom Präprozessor vor der semantischen Analyse ersetzt werden.
Es ist üblich, Struktur-/Union-/Enum-Namen mithilfe einer typedef-Deklaration in den Namensraum der gewöhnlichen Bezeichner einzufügen.
struct A { }; // introduces the name A in tag name space typedef struct A A; // first, lookup for A after "struct" finds one in tag name space // then introduces the name A in the ordinary name space struct A* p; // OK, this A is looked up in the tag name space A* q; // OK, this A is looked up in the ordinary name space
Ein bekanntes Beispiel dafür, dass derselbe Bezeichner in zwei Namensräumen verwendet wird, ist der Bezeichner stat aus der POSIX-Headerdatei sys/stat.h. Er benennt eine Funktion, wenn er als gewöhnlicher Bezeichner verwendet wird, und bezeichnet eine Struktur, wenn er als Tag verwendet wird.
Im Gegensatz zu C++ sind Aufzählungskonstanten keine Struktur-Member, und ihr Namensraum ist der Namensraum der gewöhnlichen Bezeichner. Da es in C keinen Struktur-Scope gibt, ist ihr Scope der Scope, in dem die Strukturdeklaration erscheint.
struct tagged_union { enum {INT, FLOAT, STRING} type; union { int integer; float floating_point; char *string; }; } tu; tu.type = INT; // OK in C, error in C++
|
Wenn ein Standardattribut, ein Attribut-Präfix oder ein nicht standardmäßiger Attributname nicht unterstützt wird, wird das ungültige Attribut selbst ignoriert, ohne einen Fehler zu verursachen. |
(seit C23) |
[bearbeiten] Beispiel
void foo (void) { return; } // ordinary name space, file scope struct foo { // tag name space, file scope int foo; // member name space for this struct foo, file scope enum bar { // tag name space, file scope RED // ordinary name space, file scope } bar; // member name space for this struct foo, file scope struct foo* p; // OK: uses tag/file scope name "foo" }; enum bar x; // OK: uses tag/file-scope bar // int foo; // Error: ordinary name space foo already in scope //union foo { int a, b; }; // Error: tag name space foo in scope int main(void) { goto foo; // OK uses "foo" from label name space/function scope struct foo { // tag name space, block scope (hides file scope) enum bar x; // OK, uses "bar" from tag name space/file scope }; typedef struct foo foo; // OK: uses foo from tag name space/block scope // defines block-scope ordinary foo (hides file scope) (foo){.x=RED}; // uses ordinary/block-scope foo and ordinary/file-scope RED foo:; // label name space, function scope }
[bearbeiten] Referenzen
- C17-Standard (ISO/IEC 9899:2018)
- 6.2.3 Namensräume von Bezeichnern (S. 29-30)
- C11-Standard (ISO/IEC 9899:2011)
- 6.2.3 Namensräume von Bezeichnern (S. 37)
- C99-Standard (ISO/IEC 9899:1999)
- 6.2.3 Namensräume von Bezeichnern (S. 31)
- C89/C90-Standard (ISO/IEC 9899:1990)
- 3.1.2.3 Namensräume von Bezeichnern
[bearbeiten] Siehe auch
| C++ Dokumentation für Namensauflösung
|