In article <4b2c0029$0$14550$,
Samuel Devulder wrote:Peux tu préciser en quoi c'est piégeux? J'avoue ne pas suivre ici. Tu
veux dire que les conventions ABI sont différentes entre K&R et ANSI?
Ben oui, les conventions sont differentes. En particulier, le compilo, s'il
a un prototype, peut optimiser les choses. Si tu passes plein de char a une
fonction, avec un prototype, le compilo peut tres bien te les coller sur la
pile serres les uns contre les autres, alors qu'avec l'ancienne declaration
il sera force de les etendre en int.
Si tu ne vois pas le probleme, c'est juste que tu n'as pas regarde assez loin.
Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
pres certain que ca va marcher sur ta machine courante, mais pas sur une
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
In article <4b2c0029$0$14550$426a74cc@news.free.fr>,
Samuel Devulder <samuel-dot-devulder@geensys.com> wrote:
Peux tu préciser en quoi c'est piégeux? J'avoue ne pas suivre ici. Tu
veux dire que les conventions ABI sont différentes entre K&R et ANSI?
Ben oui, les conventions sont differentes. En particulier, le compilo, s'il
a un prototype, peut optimiser les choses. Si tu passes plein de char a une
fonction, avec un prototype, le compilo peut tres bien te les coller sur la
pile serres les uns contre les autres, alors qu'avec l'ancienne declaration
il sera force de les etendre en int.
Si tu ne vois pas le probleme, c'est juste que tu n'as pas regarde assez loin.
Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
pres certain que ca va marcher sur ta machine courante, mais pas sur une
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
In article <4b2c0029$0$14550$,
Samuel Devulder wrote:Peux tu préciser en quoi c'est piégeux? J'avoue ne pas suivre ici. Tu
veux dire que les conventions ABI sont différentes entre K&R et ANSI?
Ben oui, les conventions sont differentes. En particulier, le compilo, s'il
a un prototype, peut optimiser les choses. Si tu passes plein de char a une
fonction, avec un prototype, le compilo peut tres bien te les coller sur la
pile serres les uns contre les autres, alors qu'avec l'ancienne declaration
il sera force de les etendre en int.
Si tu ne vois pas le probleme, c'est juste que tu n'as pas regarde assez loin.
Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
pres certain que ca va marcher sur ta machine courante, mais pas sur une
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
Je rajouterai : "et paf le sparc !"
Il suffit de regarder mono, seamonkey, enfin tous ces trucs codés
sur i386/amd64 qui buserrorent à donf sur ces problèmes ;-)
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
Je rajouterai : "et paf le sparc !"
Il suffit de regarder mono, seamonkey, enfin tous ces trucs codés
sur i386/amd64 qui buserrorent à donf sur ces problèmes ;-)
autre. Cas vecu: i386, amd64, ppc. Et paf le ppc.
Je rajouterai : "et paf le sparc !"
Il suffit de regarder mono, seamonkey, enfin tous ces trucs codés
sur i386/amd64 qui buserrorent à donf sur ces problèmes ;-)
De ce que tu explique, je comprends que c'est consistant, et c'est pour
ca que je ne vois pas de problèmes en mode 100% K&R.Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
Dison qu'on va se planter en loupant la bonne déclaration du proto
quelque part. Mais il y a des flags du compilo pour raler dans ces
circonstances.
De ce que tu explique, je comprends que c'est consistant, et c'est pour
ca que je ne vois pas de problèmes en mode 100% K&R.
Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
Dison qu'on va se planter en loupant la bonne déclaration du proto
quelque part. Mais il y a des flags du compilo pour raler dans ces
circonstances.
De ce que tu explique, je comprends que c'est consistant, et c'est pour
ca que je ne vois pas de problèmes en mode 100% K&R.Je ne te parle pas d'une fonction, mais d'un programme entier, censement
portable, ou tu vas convertir plusieurs centaines de fonctions d'un monde
a l'autre. Si tu le fais a la main, tu as de fortes chances de te planter sur
au moins quelques-unes.
Dison qu'on va se planter en loupant la bonne déclaration du proto
quelque part. Mais il y a des flags du compilo pour raler dans ces
circonstances.
Non, tu n'as rien compris a ce qu'on fait.
Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Non, tu n'as rien compris a ce qu'on fait.
Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Non, tu n'as rien compris a ce qu'on fait.
Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Marc Espie a écrit :Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Marc Espie a écrit :
Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.
Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Marc Espie a écrit :Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Samuel Devulder writes:Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Pour n'avoir pas à changer toutes les sources d'un coup.
On parle d'un boulot qui s'est fait quand même pour l'essentiel au début
des années 90. (Même gcc a abandonnée l'idée d'être compilable en K&R et
essaie plutôt de se rendre compilable en C++).
Samuel Devulder <samuel-dot-devulder@geensys.com> writes:
Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Pour n'avoir pas à changer toutes les sources d'un coup.
On parle d'un boulot qui s'est fait quand même pour l'essentiel au début
des années 90. (Même gcc a abandonnée l'idée d'être compilable en K&R et
essaie plutôt de se rendre compilable en C++).
Samuel Devulder writes:Question: pourquoi dans le cadre d'une ré-écriture ou un portage tient-on à
garder la compatibilité avec l'ancienne ABI?
Pour n'avoir pas à changer toutes les sources d'un coup.
On parle d'un boulot qui s'est fait quand même pour l'essentiel au début
des années 90. (Même gcc a abandonnée l'idée d'être compilable en K&R et
essaie plutôt de se rendre compilable en C++).
C'est pas pire que si dans deux fichiers C on appellait la même
fonction, mais avec des prototype différents.
f1.c:
extern double f(double a, double b);
...f(1.2, 3.4);...
f2.c:
extern char f(char a, char b);
...f('a', 'b');
f3.c:
int f(int a, int b) {return a*b;}
Comme la signature de la fonction n'intervient pas dans l'ABI, et que le
namespace est global, le linker va appeller f avec la mauvaise structure
de pile ou registre.. et bingo.. crash! C'est d'ailleurs pour cela qu'il
veut mieux mettre l'extern dans un .h unique et séparé de sorte à ce que
chaque fonction ait un et un seul prototype.
C'est pas pire que si dans deux fichiers C on appellait la même
fonction, mais avec des prototype différents.
f1.c:
extern double f(double a, double b);
...f(1.2, 3.4);...
f2.c:
extern char f(char a, char b);
...f('a', 'b');
f3.c:
int f(int a, int b) {return a*b;}
Comme la signature de la fonction n'intervient pas dans l'ABI, et que le
namespace est global, le linker va appeller f avec la mauvaise structure
de pile ou registre.. et bingo.. crash! C'est d'ailleurs pour cela qu'il
veut mieux mettre l'extern dans un .h unique et séparé de sorte à ce que
chaque fonction ait un et un seul prototype.
C'est pas pire que si dans deux fichiers C on appellait la même
fonction, mais avec des prototype différents.
f1.c:
extern double f(double a, double b);
...f(1.2, 3.4);...
f2.c:
extern char f(char a, char b);
...f('a', 'b');
f3.c:
int f(int a, int b) {return a*b;}
Comme la signature de la fonction n'intervient pas dans l'ABI, et que le
namespace est global, le linker va appeller f avec la mauvaise structure
de pile ou registre.. et bingo.. crash! C'est d'ailleurs pour cela qu'il
veut mieux mettre l'extern dans un .h unique et séparé de sorte à ce que
chaque fonction ait un et un seul prototype.
Marc Espie a écrit :Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo
avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage
tient-on à garder la compatibilité avec l'ancienne ABI? Si on change
tous les sources d'un coup il n'y a pas de pbs. Tout sera cohérent et
compatible. Je vois peu de risque la dedans.
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké avec
la nouvelle libmachin.a plante pour des raisons de convention de passage
de params sur la pile, il faut mettre à jour ce vieux code et pas
essayer de l'hybrider avec des trucs modernes.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Mais quoi qu'il en soit ca n'est pas la syntaxe ou l'ABI K&R, mais le
mixe de deux conventions différentes et pas forcément compatible qui est
risqué.
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Marc Espie a écrit :
Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.
Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo
avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage
tient-on à garder la compatibilité avec l'ancienne ABI? Si on change
tous les sources d'un coup il n'y a pas de pbs. Tout sera cohérent et
compatible. Je vois peu de risque la dedans.
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké avec
la nouvelle libmachin.a plante pour des raisons de convention de passage
de params sur la pile, il faut mettre à jour ce vieux code et pas
essayer de l'hybrider avec des trucs modernes.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Mais quoi qu'il en soit ca n'est pas la syntaxe ou l'ABI K&R, mais le
mixe de deux conventions différentes et pas forcément compatible qui est
risqué.
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Marc Espie a écrit :Non, tu n'as rien compris a ce qu'on fait.
Oui je pense.. car ya un truc qui m'échappe.Pour:
f(a)
char a;
{
}
Le prototype correspondant est
extern void f(int);
et il faut que tu utilises celui-ci pour garder l'ABI (la, le compilo
avertit
si tu te plantes).
Question: pourquoi dans le cadre d'une ré-écriture ou un portage
tient-on à garder la compatibilité avec l'ancienne ABI? Si on change
tous les sources d'un coup il n'y a pas de pbs. Tout sera cohérent et
compatible. Je vois peu de risque la dedans.
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké avec
la nouvelle libmachin.a plante pour des raisons de convention de passage
de params sur la pile, il faut mettre à jour ce vieux code et pas
essayer de l'hybrider avec des trucs modernes.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Mais quoi qu'il en soit ca n'est pas la syntaxe ou l'ABI K&R, mais le
mixe de deux conventions différentes et pas forcément compatible qui est
risqué.
Stricto sensu, il faut ecrire un truc du genre:
void(int a_)
{
char a = a_;
...
}
et verifier a la loupe si tu peux te debarrasser du a_...
Personne n'a eu l'idée de manipuler les AST (arbre syntaxique) du C pour
faire cela automatiquement? La transfo ne me semble pas super complexe
quand on a un bon AST du C (L'AST de Eclipse/CDT me semble utile pour
cela).
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké
avec la nouvelle libmachin.a plante pour des raisons de convention de
passage de params sur la pile, il faut mettre à jour ce vieux code et
pas essayer de l'hybrider avec des trucs modernes.
Tu n'as pas l'air d'avoir manipulé des applications C de plusieurs
centaines de milliers de lignes toi.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Et sur de grosses applications, ça va prendre plusieurs mois, voire
plusieurs années....
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké
avec la nouvelle libmachin.a plante pour des raisons de convention de
passage de params sur la pile, il faut mettre à jour ce vieux code et
pas essayer de l'hybrider avec des trucs modernes.
Tu n'as pas l'air d'avoir manipulé des applications C de plusieurs
centaines de milliers de lignes toi.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Et sur de grosses applications, ça va prendre plusieurs mois, voire
plusieurs années....
Peut-être que tu me parles de la situation transitoire avec un mix K&R
et ANSI.. là oui mais bon c'est transitoire. Si le vieux code linké
avec la nouvelle libmachin.a plante pour des raisons de convention de
passage de params sur la pile, il faut mettre à jour ce vieux code et
pas essayer de l'hybrider avec des trucs modernes.
Tu n'as pas l'air d'avoir manipulé des applications C de plusieurs
centaines de milliers de lignes toi.
Enfin bon peut être que si tu convertis un bout et tu finis par devoir
convertir beaucoup plus que le source d'origine. C'est sur c'est du
boulot.. mais rien n'est gratuit/magique.
Et sur de grosses applications, ça va prendre plusieurs mois, voire
plusieurs années....
Parce que certains font autrement ?
Ils ont été mal formés alors...
Parce que certains font autrement ?
Ils ont été mal formés alors...
Parce que certains font autrement ?
Ils ont été mal formés alors...