web-dev-qa-db-fra.com

Pourquoi l'ANSI C n'a-t-il pas d'espaces de noms?

Avoir des espaces de noms semble être une évidence pour la plupart des langues. Mais pour autant que je sache, ANSI C ne le prend pas en charge. Pourquoi pas? Avez-vous l'intention de l'inclure dans une future norme?

77
Pulkit Sinha

C a des espaces de noms. Un pour les balises de structure et un pour les autres types. Considérez la définition suivante:

struct foo
{
    int a;
};

typedef struct bar
{
    int a;
} foo;

Le premier a tag foo, et le dernier est transformé en type foo avec un typedef. Il n'y a toujours pas de conflit de noms. Cela est dû au fait que les balises et les types de structure (types intégrés et types typés) vivent dans des espaces de noms distincts.

Ce que C n'autorise pas est de créer nouvea un espace de noms par testament. C a été normalisé avant que cela ne soit jugé important dans une langue, et l'ajout d'espaces de noms menacerait également la compatibilité descendante, car cela nécessite un changement de nom pour fonctionner correctement. Je pense que cela peut être attribué à des détails techniques, pas à la philosophie.

EDIT: JeremyP m'a heureusement corrigé et a mentionné les espaces de noms qui m'ont manqué. Il existe des espaces de noms pour les étiquettes et pour les membres struct/union.

51
Mads Elvheim

Pour être complet, il existe plusieurs façons d'obtenir les "avantages" que vous pourriez obtenir des espaces de noms, en C.

L'une de mes méthodes préférées consiste à utiliser une structure pour héberger un tas de pointeurs de méthode qui sont l'interface de votre bibliothèque/etc.

Vous utilisez ensuite une instance externe de cette structure que vous initialisez dans votre bibliothèque pointant vers toutes vos fonctions. Cela vous permet de garder vos noms simples dans votre bibliothèque sans marcher sur l'espace de noms des clients (autre que la variable externe à portée globale, 1 variable contre éventuellement des centaines de méthodes ..)

Il y a un peu d'entretien supplémentaire impliqué mais je pense que c'est minime.

Voici un exemple:

/* 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 */

L'utilisation de . la syntaxe crée une association forte sur la méthode Library_function () Library_some_value classique. Il y a cependant quelques limitations, pour celui que vous ne pouvez pas utiliser de macros comme fonctions.

81
guest

C a des espaces de noms. La syntaxe est namespace_name. Vous pouvez même les imbriquer comme dans general_specific_name. Et si vous voulez pouvoir accéder aux noms sans écrire le nom de l'espace de noms à chaque fois, incluez les macros de préprocesseur pertinentes dans un fichier d'en-tête, par ex.

#define myfunction mylib_myfunction

C'est beaucoup plus propre que la manipulation de noms et les autres atrocités que certaines langues s'engagent à fournir des espaces de noms.

21
R..

Historiquement, les compilateurs C ne modifient pas les noms (ils le font sous Windows, mais la modification de la convention d'appel cdecl consiste uniquement à ajouter un préfixe de soulignement).

Cela facilite l'utilisation des bibliothèques C d'autres langages (y compris l'assembleur) et est l'une des raisons pour lesquelles vous voyez souvent extern "C" wrappers pour les API C++.

10
Christoph

juste des raisons historiques. personne n'a pensé à avoir quelque chose comme un espace de noms à ce moment-là. De plus, ils essayaient vraiment de garder le langage simple. Ils peuvent l'avoir à l'avenir

7
lovesh

Pas une réponse, mais pas un commentaire. C ne permet pas de définir explicitement namespace. Il a une portée variable. Par exemple:

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);
}

Vous pouvez utiliser des noms qualifiés pour les variables et les fonctions:

mylib.h

void mylib_init();
void mylib_sayhello();

La seule différence avec les espaces de noms est que vous ne pouvez pas être using et ne pouvez pas importer from mylib.

5
khachik

Parce que les gens qui veulent ajouter cette capacité à C ne se sont pas réunis et organisés pour faire pression sur les équipes d'auteurs du compilateur et sur les organismes ISO.

4
einpoklum

ANSI C a été inventé avant les espaces de noms.

4
Crashworks