134 votes

Pourquoi ne ' t C fonctions être nom tronqué ?

J'ai eu un entretien récemment et une question posée était de savoir qu'est-ce que l'utilisation d' extern "C" code C++. Je lui ai répondu que c'est pour utiliser les fonctions C dans le code C++ que le C ne pas utiliser de nom d'amputation. On m'a demandé pourquoi C ne pas utiliser de nom et d'amputation pour être honnête, je ne pouvais pas répondre.

Je comprends que lorsque le compilateur C++ compile fonctions, il donne un nom à la fonction principalement parce que nous avons peut avoir les fonctions surchargées du même nom en C++ qui doit être résolu au moment de la compilation. En C, le nom de la fonction reste la même, ou peut-être avec un _ devant elle.

Ma question est: quel est le problème avec permettant au compilateur C++ pour coder les fonctions C aussi? J'aurais cru qu'il n'a pas d'importance ce que les noms de le compilateur donne à eux. Nous appelons les fonctions de la même façon en C et C++.

187voto

Shachar Shemesh Points 561

C'était en quelque sorte répondu ci-dessus, mais je vais essayer de mettre les choses dans leur contexte.

Tout d'abord, C est venu en premier. En tant que tel, ce que le C n'est, en quelque sorte, le "par défaut". Il n'a pas de mutilation des noms, parce que cela ne fonctionne tout simplement pas. Un nom de fonction est un nom de fonction. Mondial mondial, et ainsi de suite.

Alors C++ est venu le long. C++ voulais être en mesure d'utiliser le même linker que le C, et être en mesure de lier avec le code écrit en C. Mais le C++ ne pouvait pas laisser le C "déformation" (ou absence de). Découvrez l'exemple suivant:

int function(int a);
int function();

En C++, ce sont des fonctions distinctes, avec des organes distincts. Si aucun d'entre eux sont déformés, les deux sera appelée "fonction" (ou "_function"), et l'éditeur de liens se plaindre au sujet de la redéfinition d'un symbole. C++ solution était de marquer les types d'arguments dans le nom de la fonction. Donc, on est appelés _function_int et l'autre est appelé _function_void (pas à proprement parler un régime de déformation) et la collision est évitée.

Maintenant, nous sommes de gauche avec un problème. Si int function(int a) a été défini dans un module C, et nous en sommes simplement à la prise de son en-tête (c'est à dire de la déclaration) du code C++ et en l'utilisant, le compilateur va générer une instruction de l'éditeur de liens pour importer _function_int. Lorsque la fonction a été définie, dans le module C, il n'a pas été appelé. Il a été appelé _function. Ce sera la cause d'une erreur de l'éditeur de liens.

Pour éviter cette erreur, lors de la déclaration de la fonction, de nous dire au compilateur, c'est une fonction conçue pour être reliée à, ou compilé par un compilateur C:

extern "C" int function(int a);

Le compilateur C++ sait maintenant d'importer _function plutôt que d' _function_int, et tout est bien.

45voto

unwind Points 181987

Ce n'est pas qu'ils "ne peuvent pas", ils ne sont pas, en général.

Si vous voulez appeler une fonction dans une bibliothèque C appelés foo(int x, const char *y), il n'est pas bon de laisser votre compilateur C++ mangle qui en foo_I_cCP() (ou que ce soit, juste fait un modificateur de régime sur la place ici) simplement parce qu'elle peut.

Ce nom ne résout pas, la fonction est dans C et son nom ne dépend pas de sa liste de types d'argument. De sorte que le compilateur C++ doit savoir cela, et marque que la fonction C pour éviter la déformation.

Rappelez-vous que dit C de la fonction peut être dans une bibliothèque dont le code source n'ont pas, tout ce que vous avez est le pré-compilés et l'en-tête. Si votre compilateur C++ ne peut pas le faire "c'est quelque chose de personnel", il ne peut pas changer ce qui est dans la bibliothèque, après tout.

32voto

quel est le problème avec permettant au compilateur C++ pour coder les fonctions C aussi?

Il ne serait pas de fonctions C, pas plus.

Une fonction n'est pas juste une signature et une définition; comment fonctionne une fonction est en grande partie déterminée par des facteurs comme la convention d'appel. "L'Application Binary Interface" spécifié pour une utilisation sur votre plate-forme décrit la façon dont les systèmes de parler les uns aux autres. L'ABI C++ utilisé par votre système spécifie un nom de modificateur de régime, de sorte que les programmes sur le système de savoir comment faire pour appeler des fonctions dans les bibliothèques et ainsi de suite. (Lire le C++ Itanium ABI pour un excellent exemple. Vous allez très vite voir pourquoi il est nécessaire.)

La même chose s'applique pour le C ABI sur votre système. Certains C ABIs à disposer d'un nom d'amputation régime (par exemple, Visual Studio), c'est donc moins sur la "mise hors tension de name mangling" et plus sur le passage de l'ABI C++ pour le C ABI, pour certaines fonctions. Nous C de la marque de fonctions comme les fonctions C, pour lequel le C ABI (plutôt que de l'ABI C++) est pertinente. La déclaration doit correspondre à la définition (que ce soit dans le même projet ou dans une bibliothèque tierce), sinon la déclaration est inutile. Sans cela, votre système n'est tout simplement pas savoir comment localiser/appeler ces fonctions.

Quant à savoir pourquoi les plates-formes ne définissent pas le C et le C++ ABIs être la même et de se débarrasser de ce "problème", c'est en partie historique — l'original C ABIs n'ont pas été suffisantes pour le C++, qui dispose d'espaces de noms, les classes et la surcharge des opérateurs, qui doivent tous être en quelque sorte représenté dans le nom d'un symbole dans un ordinateur de manière respectueuse de l' — mais on peut dire aussi que faire des programmes en C maintenant respecter le C++ est injuste sur la C de la communauté, qui aurait à mettre en place avec un massivement plus compliqué ABI juste pour le plaisir de quelques autres personnes qui veulent de l'interopérabilité.

19voto

MSalters Points 74024
<p>MSVC en fait <em>fait</em> mangle C noms, mais de façon simple. Il ajoute parfois <code></code> ou un autre petit nombre. Ceci se rapporte à l’appel de conventions et la nécessité pour le nettoyage de la pile.<p>Donc la prémisse est simplement erronée.</p></p>

13voto

supercat Points 25534

Il est très fréquent d'avoir des programmes qui sont partiellement écrit en C et en partie écrit dans une autre langue (souvent de l'assemblée de la langue, mais parfois, Pascal, FORTRAN, ou quelque chose d'autre). Il est également fréquent que les programmes qui contiennent différents composants écrits par des personnes différentes qui ne peut pas avoir le code source de tout.

Sur la plupart des plates-formes, il y a un cahier des charges--souvent appelé un ABI [Application Binary Interface] qui décrit ce qu'est un compilateur doit faire pour produire une fonction avec un nom particulier qui accepte les arguments de certains types particuliers et renvoie une valeur d'un type particulier. Dans certains cas, une ABI pouvez définir plus d'une "convention d'appel"; compilateurs pour de tels systèmes sont souvent un moyen d'indiquer qui, de convention d'appel doit être utilisé pour une fonction particulière. Par exemple, sur le Macintosh, la boîte à outils de la plupart des routines d'utiliser la convention d'appel Pascal, de sorte que le prototype pour quelque chose comme "LineTo" serait quelque chose comme:

/* Note that there are no underscores before the "pascal" keyword because
   the Toolbox was written in the early 1980s, before the Standard and its
   underscore convention were published */
pascal void LineTo(short x, short y);

Si tout le code dans un projet a été compilé à l'aide de la même compilateur, il n' ne pas d'importance ce nom que le compilateur a exporté pour chaque fonction, mais dans de nombreuses situations, il sera nécessaire de code C pour appeler des fonctions qui ont été compilé à l'aide d'autres outils et ne peut pas être recompilé avec le présent compilateur [et peut très bien ne pas même être en C]. Être capable de définir le nom de l'éditeur de liens est donc essentiel à l'utilisation de ces fonctions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X