OVH Cloud OVH Cloud

extern "C" et struct

6 réponses
Avatar
Marc Boyer
J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c
avec un compilo C, qui va stocker les champs de chaque
structure à sa manière, et un compilo C++ qui va les
ré-interpréter comme il veut. Le fait que le link
des deux se passe bien ne tient qu'au fait que le compilo
est gentil ?

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain

6 réponses

Avatar
Jean-Marc Bourguet
Marc Boyer writes:

J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c avec un
compilo C, qui va stocker les champs de chaque structure à sa
manière, et un compilo C++ qui va les ré-interpréter comme il
veut. Le fait que le link des deux se passe bien ne tient qu'au fait
que le compilo est gentil ?


Le extern "C" dit au compilateur C++ "tu dois interpreter cela comme
un compilateur C". Si ce qu'il faut sur la plateforme que tu utilises
est standardise (c'est en general le cas, soit formellement --
recherche ABI -- soit de fait parce que pour les autres fournisseurs
s'alignent sur ce que fait le fournisseur principal), il n'y a pas de
probleme. Sinon, au mieux tu vas te retrouver avec un switch sur ton
compilateur C++ indiquant quelle variante de l'ABI utiliser, au pire
tu vas avoir des comportements bizarres a l'execution uniquement quand
tu fais un longjmp vers une fonction qui a quatre doubles en
parametre, entre les deux tu as le fait que tu ne peux pas linker.

Naturellement, meme si l'ABI est clairement identifiee par simplement
extern "C" tu peux aussi avoir des bugs dans le support...

Note que la syntaxe de extern "C" est concue pour qu'elle soit
etendable. Par exemple faire un extern "MBC" pour la version de l'abi
utilisee par le compilateur de Marc Boyer ou un extern "Ada" pour se
linker avec de l'Ada.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
kanze
Marc Boyer wrote:
J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c avec
un compilo C, qui va stocker les champs de chaque structure à
sa manière, et un compilo C++ qui va les ré-interpréter comme
il veut. Le fait que le link des deux se passe bien ne tient
qu'au fait que le compilo est gentil ?


En toute rigueur, oui. Qu'est-ce que tu veux de plus ? La norme
C++ ne peut pas imposer quoique ce soit au compilateur C. Il
peut même y avoir plusieurs compilateurs C sur la machine, avec
des organisations (et la décoration des noms, et les conventions
d'appel) différentes. Ou il peut ne pas y avoir de compilateur C
du tout.

L'intention est à mon avis claire, le compilateur C++ doit
essayer à faire en sort que ça passe avec au moins un
compilateur C. J'ai même l'impression qu'en ce qui concerne les
struct, que l'intention est qu'une classe POD soit compatible
avec ce que fait le compilateur (ou un des compilateurs) C.

Dans la pratique, sur beaucoup de systèmes aujourd'hui, la API
système est défini en termes de C, tous les compilateurs C y
conforme, et ça serait un très mauvais compilateur C++ qui n'y
conformerait pas. En somme, je ne m'y inquièterais pas.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
kanze
Jean-Marc Bourguet wrote:
Marc Boyer writes:

J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c avec
un compilo C, qui va stocker les champs de chaque structure
à sa manière, et un compilo C++ qui va les ré-interpréter
comme il veut. Le fait que le link des deux se passe bien ne
tient qu'au fait que le compilo est gentil ?


Le extern "C" dit au compilateur C++ "tu dois interpreter cela
comme un compilateur C".


Pas du tout. D'abord, on se démande bien comment il pourrait
interpréter certaines choses comme un compilateur C -- j'ai un
cas, par exemple, ou une fonction « extern "C" » renvoie un
std::auto_ptr. Le code dans un bloc « extern "C" » reste du C++,
et non du C.

Deuxièmement, si l'intention est bien de pouvoir appeler les
fonctions compilées en C, il reste la question : quel C ?
Mettons que la plateforme a deux compilateurs C, avec des
conventions d'appel différentes. Ou qu'il n'en a pas du tout.

La norme C++ ne peut pas imposer la présence d'un compilateur C.
Elle ne peut pas non plus imposer que plusieurs compilateurs C
respectent la même API. Du coup, tout ce qu'elle peut faire,
c'est d'exprimer une intention. Toute la reste, c'est de la
qualité de l'implémentation (c-à-d, que le compilo est gentil).

Si ce qu'il faut sur la plateforme que tu utilises est
standardise (c'est en general le cas, soit formellement --
recherche ABI -- soit de fait parce que pour les autres
fournisseurs s'alignent sur ce que fait le fournisseur
principal), il n'y a pas de probleme.


Dans la pratique.

En ce qui concerne les struct, il n'a même pas besoin de
l'« extern "C" », au moins dans la pratique ; il suffit que la
classe soit un PODS. (Je crois que ça fait partie de l'intention
de la norme C++ aussi, même si ce n'est pas aussi clairement
exprimé.)

[...]
Note que la syntaxe de extern "C" est concue pour qu'elle soit
etendable. Par exemple faire un extern "MBC" pour la version
de l'abi utilisee par le compilateur de Marc Boyer ou un
extern "Ada" pour se linker avec de l'Ada.


Tout à fait. Note cependant qu'il faudrait dans ces cas un peu
plus de documentation : comment les appels, les structures,
etc., sont mappés. Parce que le code dans le bloc reste du C++,
non de l'Ada, et qu'il faut bien préciser comment déclarer en
C++ ce qui est défini en Ada. On pourrait par exemple imaginer
que le compilateur exige que les fonctions dans un bloc « extern
"Fortran" » n'utilisent que des types référence comme
paramètres.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Marc Boyer
Le 09-02-2006, kanze a écrit :
Marc Boyer wrote:
J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c avec
un compilo C, qui va stocker les champs de chaque structure à
sa manière, et un compilo C++ qui va les ré-interpréter comme
il veut. Le fait que le link des deux se passe bien ne tient
qu'au fait que le compilo est gentil ?


En toute rigueur, oui. Qu'est-ce que tu veux de plus ?


Pas grand chose, juste être sur que j'avais bien compris.

La norme
C++ ne peut pas imposer quoique ce soit au compilateur C. Il
peut même y avoir plusieurs compilateurs C sur la machine, avec
des organisations (et la décoration des noms, et les conventions
d'appel) différentes. Ou il peut ne pas y avoir de compilateur C
du tout.


Mais il pourrait y avoir des ABI qui fixent des règles.

L'intention est à mon avis claire, le compilateur C++ doit
essayer à faire en sort que ça passe avec au moins un
compilateur C. J'ai même l'impression qu'en ce qui concerne les
struct, que l'intention est qu'une classe POD soit compatible
avec ce que fait le compilateur (ou un des compilateurs) C.

Dans la pratique, sur beaucoup de systèmes aujourd'hui, la API
système est défini en termes de C, tous les compilateurs C y
conforme, et ça serait un très mauvais compilateur C++ qui n'y
conformerait pas. En somme, je ne m'y inquièterais pas.


Moi non plus.

Marc Boyer
--
Entre le fort et le faible, c'est la liberte qui opprime et le droit
qui libere. Henri Lacordaire, Dominicain


Avatar
Gabriel Dos Reis
"kanze" writes:

[...]

| En ce qui concerne les struct, il n'a même pas besoin de
| l'« extern "C" », au moins dans la pratique ; il suffit que la
| classe soit un PODS. (Je crois que ça fait partie de l'intention
| de la norme C++ aussi, même si ce n'est pas aussi clairement
^^^^^^^^^^^^^^^^^^^^^
| exprimé.)

Maintenant, il est question de faire des procès d'intention.
Il est certainement le voeux exprimé du syndicat des écrivains de
compilateurs, mais je ne penses pas que ce soit l'intention du
comité. Et de récents débats sur la question me conforte dans cette
idée.

-- Gaby
Avatar
kanze
Marc Boyer wrote:
Marc Boyer wrote:
J'ai un code C qui lit un fichier, et remplis un tableau
de structures.

J'aimerais reprendre ce code en C++. Bon, dans la pratique,
un coup de
extern "C" {
#include "parse_file.h"
}

Et le fichier parse_file.h contient des définitions
de structure
typedef struct {
int id;
char nom[30];
...
} Noeud;

Mais dans la théorie, je vais compiler mon parse_file.c avec
un compilo C, qui va stocker les champs de chaque structure à
sa manière, et un compilo C++ qui va les ré-interpréter comme
il veut. Le fait que le link des deux se passe bien ne tient
qu'au fait que le compilo est gentil ?


En toute rigueur, oui. Qu'est-ce que tu veux de plus ?


Pas grand chose, juste être sur que j'avais bien compris.

La norme C++ ne peut pas imposer quoique ce soit au
compilateur C. Il peut même y avoir plusieurs compilateurs C
sur la machine, avec des organisations (et la décoration des
noms, et les conventions d'appel) différentes. Ou il peut ne
pas y avoir de compilateur C du tout.


Mais il pourrait y avoir des ABI qui fixent des règles.


Il pourrait y avoir, mais la norme ne l'impose pas. On peut très
bien implémenter le C++ sur une plateforme où il n'y a pas de
compilateur C.

Dans les cas où il y a une ABI qui fixe les règles pour des
struct en C, je vois mal un compilateur C++ qui ne s'y plie pas
pour des classes POD. Mais dans la mesure où la norme doit
fonctionner même dans l'absense d'une telle ABI, elle ne peut
pas en exiger l'adhérance quand elle existe. Donc, c'est une
question de la qualité de l'implémentation.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34