Warum hat ANSI C keine Namespaces?

Lesezeit: 9 Minuten

Benutzeravatar von Pulkit Sinha
Pulkit Sinha

Namensräume zu haben, scheint für die meisten Sprachen ein Kinderspiel zu sein. Aber soweit ich das beurteilen kann, unterstützt ANSI C es nicht. Warum nicht? Gibt es Pläne, es in einen zukünftigen Standard aufzunehmen?

  • Verwenden Sie C++ als C-mit-Namensraum!

    – Khaled Alshaya

    9. Dezember 2010 um 8:20 Uhr

  • Kann ich natürlich, würde es aber trotzdem gerne wissen

    – Pulkit Sinha

    9. Dezember 2010 um 8:23 Uhr

  • 2 Dinge. Eine unnötige Unterscheidungssyntax: Alle anderen Sprachen mit Namensräumen verwenden einfach ‘.’ als Trennzeichen, da es nicht zweideutig mit anderen Verwendungen von ‘.’ ist. Und was noch wichtiger ist: C++ hat nie eine Scoped Using-Direktive eingeführt. Das bedeutete, dass Programmierer zu viel Gebrauch von Direktiven machten, um Namespaces in den globalen Gültigkeitsbereich zu importieren. Das bedeutete, dass das C++-Standardkomitee jetzt keine neuen Funktionen zu std:: hinzufügen kann, da die Menge an Code, der dadurch kaputt gehen würde, die Partitionierung überflüssig gemacht hat.

    – Chris Becke

    9. Dezember 2010 um 8:40 Uhr

  • @Chris Becke: Ich mag unverwechselbare Syntax. Ich möchte gerne wissen, ob ich eine Klasse in einem Namensraum oder ein Mitglied in einer Klasse betrachte.

    – JeremyP

    9. Dezember 2010 um 9:03 Uhr


  • @ChrisBecke, das ist ein paar Jahre zu spät, aber es ist interessant, dass Sie argumentieren, dass C++-Namespaces schlecht implementiert wurden, also sollten sie nicht in C implementiert werden. Dann stellen Sie fest, dass andere Sprachen sie ohne die Aufhänger von C++ implementieren. Wenn andere Sprachen das können, warum nicht ihnen C vorstellen?

    – weberc2

    22. Oktober 2013 um 14:54 Uhr

Benutzeravatar des Gastes
Gast

Der Vollständigkeit halber gibt es mehrere Möglichkeiten, die “Vorteile” zu erzielen, die Sie möglicherweise von Namespaces in C erhalten.

Eine meiner Lieblingsmethoden ist die Verwendung einer Struktur, um eine Reihe von Methodenzeigern zu beherbergen, die die Schnittstelle zu Ihrer Bibliothek/usw. sind.

Sie verwenden dann eine externe Instanz dieser Struktur, die Sie in Ihrer Bibliothek initialisieren und auf alle Ihre Funktionen verweisen. Auf diese Weise können Sie Ihre Namen in Ihrer Bibliothek einfach halten, ohne auf den Namensraum des Clients zu treten (anders als die externe Variable im globalen Bereich, 1 Variable im Vergleich zu möglicherweise Hunderten von Methoden..)

Es gibt einige zusätzliche Wartungsarbeiten, aber ich denke, dass es minimal ist.

Hier ist ein Beispiel:

/* interface.h */

struct library {
    const int some_value;
    void (*method1)(void);
    void (*method2)(int);
    /* ... */
};

extern const struct library Library;
/* interface.h */

/* interface.c */
#include "interface.h"

void method1(void)
{
   ...
}
void method2(int arg)
{
   ...
}

const struct library Library = {
    .method1 = method1,
    .method2 = method2,
    .some_value = 36
};
/* end interface.c */

/* client code */
#include "interface.h"

int main(void)
{
    Library.method1();
    Library.method2(5);
    printf("%d\n", Library.some_value);
    return 0;
}
/* end */

Die Verwendung von . Syntax schafft eine starke Assoziation zur klassischen Methode Library_function() Library_some_value. Es gibt jedoch einige Einschränkungen, zum einen können Sie Makros nicht als Funktionen verwenden.

  • … und sind Compiler intelligent genug, um den Funktionszeiger zur Kompilierzeit zu “dereferenzieren”, wenn Sie dies tun library.method1()?

    – einpoklum

    1. Oktober 2015 um 11:37 Uhr

  • Das ist so toll. Eine Sache, die ich hinzufügen möchte, ich versuche, alle meine Funktionen in meinem zu machen .c Dateien standardmäßig statisch, daher sind die einzigen Funktionen, die offengelegt werden, diejenigen, die explizit in der Datei exponiert sind const struct Definition in der .c Datei.

    – lastmjs

    1. Februar 2017 um 19:53 Uhr

  • Das ist eine großartige Idee, aber wie gehen Sie mit Konstanten und Aufzählungen um?

    – nowox

    19. Juli 2017 um 14:43 Uhr

  • @einpoklum – Entschuldigung für Necro, aber zumindest ab Version 6.3.0 berechnet gcc die tatsächliche Adresse von function1/method2 beim Kompilieren mit beiden -O2 und -flto. Wenn Sie solche Bibliotheken nicht zusammen mit Ihrer eigenen Quelle kompilieren, fügt dieser Ansatz den Funktionsaufrufen etwas Overhead hinzu.

    – Alex Reinking

    4. März 2018 um 8:11 Uhr

  • @AlexReinking: Nun, das ist nett, aber wir würden diese Funktionen niemals inline bekommen. Und – Necro’ing ist großartig, keine Entschuldigung nötig.

    – einpoklum

    4. März 2018 um 10:00 Uhr

C hat Namespaces. Eine für Struktur-Tags und eine für andere Typen. Betrachten Sie die folgende Definition:

struct foo
{
    int a;
};

typedef struct bar
{
    int a;
} foo;

Der erste hat Schild foo, und letzteres wird mit einem typedef in den Typ foo umgewandelt. Es kommt immer noch nicht zu Namenskonflikten. Dies liegt daran, dass Struktur-Tags und -Typen (eingebaute Typen und typdefinierte Typen) in separaten Namespaces leben.

Was C nicht erlaubt, ist das Erstellen Neu Namensraum nach Belieben. C wurde standardisiert, bevor dies in einer Sprache als wichtig erachtet wurde, und das Hinzufügen von Namespaces würde auch die Abwärtskompatibilität gefährden, da es erforderlich ist, dass Namensverstümmelungen richtig funktionieren. Ich denke, dies kann auf technische Aspekte und nicht auf Philosophie zurückgeführt werden.

EDIT: JeremyP hat mich glücklicherweise korrigiert und die Namespaces erwähnt, die ich verpasst habe. Es gibt auch Namespaces für Labels und für Struct/Union-Mitglieder.

  • Es gibt tatsächlich mehr als zwei Namensräume. Zusätzlich zu den beiden, die Sie erwähnen, gibt es einen Namensraum für Labels und Namensräume für die Mitglieder jeder Struktur und Union.

    – JeremyP

    9. Dezember 2010 um 9:00 Uhr

  • @JeremyP: Vielen Dank für die Korrektur. Ich habe das nur aus dem Gedächtnis geschrieben, ich habe den Standard nicht überprüft 🙂

    Mads Elvheim

    9. Dezember 2010 um 19:22 Uhr

  • Was ist mit Namespace für Funktionen?

    – themihai

    3. Juli 2016 um 12:42 Uhr

  • Dies kann durchaus als Namespaces bezeichnet werden, aber ich glaube, dies sind nicht die Art von Namespaces, nach denen das OP gefragt hat.

    – avl_schweden

    18. August 2017 um 12:53 Uhr

  • @jterm Nein. Ich befürworte nicht das Hacken von C-Features, sondern stelle lediglich die Fakten dar. Jeder struct definition deklariert einen neuen Namensraum für seine Mitglieder. Ich plädiere nicht dafür, diese Tatsache auszunutzen, und kenne seitdem keine Mittel, um sie auszunutzen structs können keine statischen Mitglieder haben.

    – JeremyP

    28. August 2018 um 17:16 Uhr

C hat Namensräume. Die Syntax ist namespace_name. Sie können sie sogar wie in verschachteln general_specific_name. Und wenn Sie auf Namen zugreifen möchten, ohne jedes Mal den Namespace-Namen ausschreiben zu müssen, fügen Sie die entsprechenden Präprozessor-Makros in eine Header-Datei ein, z

#define myfunction mylib_myfunction

Dies ist viel sauberer als Namensverstümmelung und die anderen Gräueltaten, die bestimmte Sprachen zur Bereitstellung von Namensräumen begehen.

  • Ich sehe das anders. Das Komplizieren der Grammatik, das Einführen von Namensverstümmelungen bei Symbolen usw., um etwas zu erreichen, das mit dem Präprozessor bereits trivial war, würde ich als schmutzigen Hack und schlechtes Design bezeichnen.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    3. Juli 2013 um 21:27 Uhr

  • Ich verstehe nicht, wie Sie diese Position wirklich unterstützen können. Fragen Sie die Javascript-Community nach der Integration von Projekten, wenn jedes andere System einen anderen hausgemachten Hack zur Implementierung von Namespaces hat. Ich habe noch nie gehört, dass sich jemand über das Schlüsselwort „Namespace“ oder „Paket“ beschwert hat, das seiner Sprache zu viel Komplexität verleiht. Andererseits kann der Versuch, mit Makros übersäten Code zu debuggen, schnell haarig werden!

    – weberc2

    4. Juli 2013 um 0:33 Uhr

  • @R.. Das würde nicht passieren, wenn die Namensverstümmelung in C++ standardisiert wäre. Dies allein würde der ABI-Kompatibilität nicht helfen, aber das Namenszuordnungsproblem definitiv beheben.

    – Malcolm

    8. Juli 2013 um 10:27 Uhr

  • Dies sind keine Namespaces, dies verwendet eine Namenskonvention, um schlecht nachzuahmen, was Namespaces Ihnen geben.

    – Claudius

    23. März 2015 um 17:49 Uhr

  • Ich finde es überwältigend, dass C-Leute dies tatsächlich mit einem ernsten Gesicht argumentieren. Es gibt viele Funktionen in C++ mit scharfen Kanten, die den Leuten Kummer bereiten. Namespaces gehören nicht zu diesen Features. Sie sind großartig, sie funktionieren sehr gut. Und nichts ist mit dem Präprozessor trivial, fürs Protokoll. Schließlich ist das Entwirren von Namen trivial, es gibt viele Befehlszeilenprogramme, die dies für Sie erledigen.

    – Nir Friedman

    14. Juni 2015 um 14:36 ​​Uhr

Historisch gesehen entstellen C-Compiler keine Namen (sie tun dies unter Windows, aber das Entstellen für die cdecl Aufrufkonvention besteht nur darin, einen Unterstrich als Präfix hinzuzufügen).

Dies erleichtert die Verwendung von C-Bibliotheken aus anderen Sprachen (einschließlich Assembler) und ist einer der Gründe, warum Sie häufig sehen extern "C" Wrapper für C++-APIs.

loveshs Benutzeravatar
liebtsch

nur historische Gründe. Niemand dachte damals daran, so etwas wie einen Namensraum zu haben. Außerdem haben sie wirklich versucht, die Sprache einfach zu halten. Sie können es in der Zukunft haben

  • Gibt es im Standardkomitee eine Bewegung, um in Zukunft Namensräume zu C hinzuzufügen? Möglich mit der Umstellung auf C/C++-Modul könnte dies in Zukunft einfacher werden?

    – Lanox

    13. Februar 2015 um 13:13 Uhr

  • @lanoxx Aus Gründen der Abwärtskompatibilität besteht keine Absicht, Namespaces zu C hinzuzufügen.

    – themihai

    6. September 2016 um 13:10 Uhr

khachiks Benutzeravatar
khachik

Keine Antwort, aber kein Kommentar. C bietet keine Möglichkeit zur Definition namespace ausdrücklich. Es hat einen variablen Umfang. Zum Beispiel:

int i=10;

struct ex {
  int i;
}

void foo() {
  int i=0;
}

void bar() {
  int i=5;
  foo();
  printf("my i=%d\n", i);
}

void foobar() {
  foo();
  bar();
  printf("my i=%d\n", i);
}

Sie können qualifizierte Namen für Variablen und Funktionen verwenden:

mylib.h

void mylib_init();
void mylib_sayhello();

Der einzige Unterschied zu Namespaces besteht darin, dass Sie nicht sein können using und kann nicht importieren from mylib.

  • Gibt es im Standardkomitee eine Bewegung, um in Zukunft Namensräume zu C hinzuzufügen? Möglich mit der Umstellung auf C/C++-Modul könnte dies in Zukunft einfacher werden?

    – Lanox

    13. Februar 2015 um 13:13 Uhr

  • @lanoxx Aus Gründen der Abwärtskompatibilität besteht keine Absicht, Namespaces zu C hinzuzufügen.

    – themihai

    6. September 2016 um 13:10 Uhr

Benutzeravatar von Crashworks
Absturz

ANSI C wurde erfunden, bevor es Namespaces gab.

  • Es war? Die erste ANSI C-Spezifikation war 1989. Ich bin mir ziemlich sicher, dass Namespaces (in irgendeiner Form) schon vorher in Programmiersprachen vorhanden waren. Ada zum Beispiel wurde 1983 standardisiert und hatte Pakete als Namespaces. Diese wiederum basierten im Wesentlichen auf Modula-2-Modulen.

    – NUR MEINE richtige MEINUNG

    9. Dezember 2010 um 11:09 Uhr

  • Ich würde die Erfindung von ANSI C nicht auf den Zeitpunkt datieren, an dem seine Spezifikation offiziell angenommen wurde; Die Sprache existierte vorher, und die Spezifikation dokumentierte nur, was bereits vorhanden war. Obwohl man aufgrund einiger Antworten auf dieser Site denken könnte, dass die Spezifikation zuerst kam und der erste Compiler erst im Nachhinein.

    – Absturz

    9. Dezember 2010 um 18:17 Uhr

  • ANSI C hatte einige signifikante Unterschiede zu Pre-ANSI C, aber Namespaces gehörten nicht dazu.

    – dan04

    20. Februar 2011 um 9:49 Uhr

  • Inzwischen schreibe ich es im Jahr 2020, lange nachdem Namensräume entstanden sind. Die neuesten C-Normen haben sie noch nicht. So sehr C Sinn macht, ist dies eine Funktion, die schmerzlich fehlt.

    Benutzer14222280

    25. September 2020 um 8:59 Uhr


1422440cookie-checkWarum hat ANSI C keine Namespaces?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy