Mittwoch, Januar 29, 2020

Verständnis C namespaces

Zitat aus hier,

In C gibt es zwei verschiedene namespaces von Typen: ein Namensraum struct/union/enum-tag-Namen und einem namespace-von typedef-Namen.

Namen.c

$ cat name.c
#include<stdio.h>

typedef long long long2;

int long2 () {
    return 4;
}

int main() {

    printf("hello, world!");
    return 0;
}
$ gcc name.c -o name
name.c:4: error: 'long2' redeclared as different kind of symbol
name.c:3: error: previous declaration of 'long2' was here
$

name2.c

$ cat name2.c
#include<stdio.h>

int four() {
    return 4;
}

struct dummy {
    int member;
};

int main() {

    struct dummy four;
}

$ gcc name2.c -o name2
$ 

Ich versuche zu verstehen C namespace-Konflikte.

  • Im ersten Fall, warum gibt es einen Konflikt? Tun Funktionen gehören auch die typedef-namespace?

  • Im zweiten Fall, warum gibt es keinen Konflikt überhaupt? Die Funktion und die variable beide benannt sind die vier. Warum tut der compiler zulassen? Wie ist &four soll gelöst werden?

InformationsquelleAutor Lazer | 2010-09-25

3 Kommentare

  1. 27

    C hat vier verschiedene Namensräume für Bezeichner:

    • Label-Namen (goto– Typ).
    • Tags (Namen von Strukturen, unions und Aufzählungen.
    • Mitglieder von Strukturen und unions (diese haben einen separaten Namensraum pro Struktur/union).
    • Alle anderen Bezeichner (Funktion, Namen, Objekt-Namen, den Typ(def) Namen, enumeration-Konstanten, etc.).

    Siehe auch C99 6.2.3.

    Also Ihr zwei Frage beantwortet werden können wie:

    1. Ja, Funktionsnamen und typedef-Namen, die den gleichen Namen teilen.
    2. Kein Konflikt, weil der compiler benutzen Umfang (Regeln für Funktions-oder Objektnamen). Die id in der main ist, sagte zu Schatten der globalen Funktion name, etwas, was dein compiler wird Sie warnen, wenn Sie die Warnung Level hoch genug ist.
    • Tut structs/unions/Enumerationen, die teilen sich einen Namensraum? also, kann struct T und union T gehen gut zusammen?
  2. 7

    Aber der entscheidende Punkt auf Ihrem Beispiele nicht über den namespace, aber der Raum der Namen.

    In Namen.c, beide long2 sind „normale Kennzeichen“ (den gleichen Namen teilen), und beide definiert sind, in demselben Umfang ab, so liegt ein Konflikt vor. (C99 §6.7/3)

    Wenn name2.c die lokale variable four ist in einem Bereich, der tiefer als die Funktion four, so wird die variable verbirgt die Funktion four (C99 §6.2.1/4).

  3. 6

    Deinem 2. Beispiel zeigt nicht „kein Konflikt“. Es ist ein Konflikt! Versuchen Sie dies:

    #include <stdio.h>
    int four(void) { return 4; }
    struct dummy { int member; };
    int main(void) {
        struct dummy four;
        four.member = four();
    }

    Und jetzt diese

    #include <stdio.h>
    int four(void) { return 4; }
    struct dummy { int member; };
    int main(void) {
        int (*fx)(void) = four; /* "save" function */
        struct dummy four;     /* hide it         */
        four.member = fx();    /* use "hidden" fx */
    }

    In deinem 2. Beispiel wird die variable four verbirgt die Funktion four().

Kostenlose Online-Tests