Pour essayer de contraindre Emmanuel Dreyfus au silence, lui qui ne
cesse de glisser des «tu devrais écrire sur tel ou tel sujet»[1], je
n'ai rien trouvé de mieux que de raconter comment je me suis occupé
pendant le mois de juillet dernier.
Vous pouvez donc en admirer le résultat en
http://www.onlamp.com/pub/a/bsd/2003/10/02/openbsd_gcc.html
Bonne lecture.
[1] afin de diminuer, pendant ce temps, ma productivité dans d'autres
domaines, bien entendu.
- Quand vous voyez un autoconf au milieu de la route qui vous fait des signaux, vous faites quoi ?
- Ben je m'arrete.
- Moi non. C'est pourquoi je n'ai plus ma licence GNU.
espie
In article , Erwan David wrote:
Ben c'est un bug du source ça, en C le tableau de taille nulle est un comportement indéfini... je peux me tromper, mais il me semble qu'en C99, ca existe.
In article <85vfr6pbbc.fsf@bretagne.rail.eu.org>,
Erwan David <erwan@rail.eu.org> wrote:
Ben c'est un bug du source ça, en C le tableau de taille nulle est un
comportement indéfini...
je peux me tromper, mais il me semble qu'en C99, ca existe.
Ben c'est un bug du source ça, en C le tableau de taille nulle est un comportement indéfini... je peux me tromper, mais il me semble qu'en C99, ca existe.
espie
In article <1g2a2yo.1iolz2c7qbr15N%, Emmanuel Dreyfus wrote:
Michel Talon wrote:
Ce qui veut dire qu'il est défini différemment par gcc et icc ! (quelque chose comme taille 0 pour l'un et 1 pour l'autre si je me souviens bien, ceci entraînant un bug quelque part).
Ben le bug c'est qu'il ne devrait pas y avoir de tabkleau de taille nulle dans les sources. Ca sert à quoi un tableau de tailel nulle, à part se vautrer quand on accède à son contenu? Pourtant, la construction est classique.
struct machin { int un_truc; int un_deuxieme_truc; char s[0]; };
struct machin * new_machin(const char *s) { struct machin *m; size_t n = strlen(s)+1; m = malloc(sizeof(struct machin)+n); if (!m) return 0; m->un_truc = 0; m->un_deuxieme_truc = 0; memcpy(&m->s, s, n); return m; }
Sans tableaux de taille nulle, c'est parfois un peu plus chiant cote gestion des tailles...
In article <1g2a2yo.1iolz2c7qbr15N%manu@netbsd.org>,
Emmanuel Dreyfus <manu@netbsd.org> wrote:
Michel Talon <talon@lpthe.jussieu.fr> wrote:
Ce qui veut dire qu'il est défini différemment par gcc et icc !
(quelque chose comme taille 0 pour l'un et 1 pour l'autre si je me
souviens bien, ceci entraînant un bug quelque part).
Ben le bug c'est qu'il ne devrait pas y avoir de tabkleau de taille
nulle dans les sources. Ca sert à quoi un tableau de tailel nulle, à
part se vautrer quand on accède à son contenu?
Pourtant, la construction est classique.
struct machin
{
int un_truc;
int un_deuxieme_truc;
char s[0];
};
struct machin *
new_machin(const char *s)
{
struct machin *m;
size_t n = strlen(s)+1;
m = malloc(sizeof(struct machin)+n);
if (!m)
return 0;
m->un_truc = 0;
m->un_deuxieme_truc = 0;
memcpy(&m->s, s, n);
return m;
}
Sans tableaux de taille nulle, c'est parfois un peu plus chiant cote
gestion des tailles...
In article <1g2a2yo.1iolz2c7qbr15N%, Emmanuel Dreyfus wrote:
Michel Talon wrote:
Ce qui veut dire qu'il est défini différemment par gcc et icc ! (quelque chose comme taille 0 pour l'un et 1 pour l'autre si je me souviens bien, ceci entraînant un bug quelque part).
Ben le bug c'est qu'il ne devrait pas y avoir de tabkleau de taille nulle dans les sources. Ca sert à quoi un tableau de tailel nulle, à part se vautrer quand on accède à son contenu? Pourtant, la construction est classique.
struct machin { int un_truc; int un_deuxieme_truc; char s[0]; };
struct machin * new_machin(const char *s) { struct machin *m; size_t n = strlen(s)+1; m = malloc(sizeof(struct machin)+n); if (!m) return 0; m->un_truc = 0; m->un_deuxieme_truc = 0; memcpy(&m->s, s, n); return m; }
Sans tableaux de taille nulle, c'est parfois un peu plus chiant cote gestion des tailles...
pornin
According to Marc Espie :
Pourtant, la construction est classique.
struct machin { int un_truc; int un_deuxieme_truc; char s[0]; };
C'est classique mais incorrect ; surtout, c'est supporté différemment suivant les compilateurs, ce qui met la zone. Voilà la manière de faire en bon C standard :
struct machin { int un_truc; int un_deuxieme_truc; char s[1]; };
Note l'usage du "offsetof" (macro standard définie dans <stddef.h>) qui permet de faire une allocation de la bonne taille, prenant en compte l'alignement.
En C99, on peut aussi faire comme ça :
struct machin { int un_truc; int un_deuxieme_truc; char s[]; };
et utiliser un sizeof dans le malloc(). Le champ "s" est un tableau non pas de taille nulle mais de type incomplet (sans taille déclarée). C'est un "flexible array member" d'après la norme (paragraphe 6.7.2.1/16). Cette méthode est standard, et marchera sur tout compilateur où la macro __STDC_VERSION__ est définie à une constante entière supérieure ou égale à 199901L.
Toujours est-il que la méthode avec tableau de taille nulle ne doit pas être utilisée, puisqu'il existe une méthode fonctionnellement équivalente (celle avec le "offsetof") qui, elle, marchera partout.
--Thomas Pornin
According to Marc Espie <espie@nerim.net>:
Pourtant, la construction est classique.
struct machin
{
int un_truc;
int un_deuxieme_truc;
char s[0];
};
C'est classique mais incorrect ; surtout, c'est supporté différemment
suivant les compilateurs, ce qui met la zone. Voilà la manière de
faire en bon C standard :
struct machin {
int un_truc;
int un_deuxieme_truc;
char s[1];
};
Note l'usage du "offsetof" (macro standard définie dans <stddef.h>)
qui permet de faire une allocation de la bonne taille, prenant en
compte l'alignement.
En C99, on peut aussi faire comme ça :
struct machin {
int un_truc;
int un_deuxieme_truc;
char s[];
};
et utiliser un sizeof dans le malloc(). Le champ "s" est un tableau non
pas de taille nulle mais de type incomplet (sans taille déclarée). C'est
un "flexible array member" d'après la norme (paragraphe 6.7.2.1/16).
Cette méthode est standard, et marchera sur tout compilateur où la macro
__STDC_VERSION__ est définie à une constante entière supérieure ou égale
à 199901L.
Toujours est-il que la méthode avec tableau de taille nulle ne doit
pas être utilisée, puisqu'il existe une méthode fonctionnellement
équivalente (celle avec le "offsetof") qui, elle, marchera partout.
struct machin { int un_truc; int un_deuxieme_truc; char s[0]; };
C'est classique mais incorrect ; surtout, c'est supporté différemment suivant les compilateurs, ce qui met la zone. Voilà la manière de faire en bon C standard :
struct machin { int un_truc; int un_deuxieme_truc; char s[1]; };
Note l'usage du "offsetof" (macro standard définie dans <stddef.h>) qui permet de faire une allocation de la bonne taille, prenant en compte l'alignement.
En C99, on peut aussi faire comme ça :
struct machin { int un_truc; int un_deuxieme_truc; char s[]; };
et utiliser un sizeof dans le malloc(). Le champ "s" est un tableau non pas de taille nulle mais de type incomplet (sans taille déclarée). C'est un "flexible array member" d'après la norme (paragraphe 6.7.2.1/16). Cette méthode est standard, et marchera sur tout compilateur où la macro __STDC_VERSION__ est définie à une constante entière supérieure ou égale à 199901L.
Toujours est-il que la méthode avec tableau de taille nulle ne doit pas être utilisée, puisqu'il existe une méthode fonctionnellement équivalente (celle avec le "offsetof") qui, elle, marchera partout.
--Thomas Pornin
pornin
According to Marc Espie :
je peux me tromper, mais il me semble qu'en C99, ca existe.
En l'occurrence tu confonds effectivement avec le "flexible array member" que je décris dans un autre message, qui est un cas de tableau de taille indéfinie (et non de taille nulle). Quand un tableau a une taille définie, elle doit être strictement positive (cf 6.7.5.2/1 pour les tableaux de taille constante, et 6.7.5.2/5 pour les tableaux de taille variable ; dans les deux cas, c'est "greater than zero").
--Thomas Pornin
According to Marc Espie <espie@nerim.net>:
je peux me tromper, mais il me semble qu'en C99, ca existe.
En l'occurrence tu confonds effectivement avec le "flexible array
member" que je décris dans un autre message, qui est un cas de tableau
de taille indéfinie (et non de taille nulle). Quand un tableau a une
taille définie, elle doit être strictement positive (cf 6.7.5.2/1 pour
les tableaux de taille constante, et 6.7.5.2/5 pour les tableaux de
taille variable ; dans les deux cas, c'est "greater than zero").
je peux me tromper, mais il me semble qu'en C99, ca existe.
En l'occurrence tu confonds effectivement avec le "flexible array member" que je décris dans un autre message, qui est un cas de tableau de taille indéfinie (et non de taille nulle). Quand un tableau a une taille définie, elle doit être strictement positive (cf 6.7.5.2/1 pour les tableaux de taille constante, et 6.7.5.2/5 pour les tableaux de taille variable ; dans les deux cas, c'est "greater than zero").
--Thomas Pornin
Marwan FeanoR/var Burelle
On Fri, 3 Oct 2003 12:39:29 +0000 (UTC) Miod Vallat wrote:
Dans le cas de gcc, tout le monde s'accorde à dire qu'un compilateur moins obscur, moins bogué, plus rapide et sous licence libre non-GPL serait le bienvenu. Mais pour l'instant aucun des efforts dans ce sens n'a donné de résultats concrets. TenDRA est encore loin d'être une alternative envisageable à gcc, même sur x86 seulement ; et d'autres, comme lcc ou le compilateur de plan9 ne sont malheureusement pas libres.
Pour ce qui est de TenDRA, je dirais même que le résultat est très loin d'être satisfaisant. Juste sur un petit bout code tout petit, le binaire généré par TenDRA est plus gros et plus lent qu'un binaire généré par gcc -g (sur mon FreeBSD, sur x86...)
On pourrait reprendre pcc, le moderniser et écrire un optimiseur (après tout, c'est bien ce qu'un certain Richard S. a fait il y a une vingtaine d'années...), mais pour l'instant personne ne s'est laissé tenter(excepté Anders Magnusson, qui a maintenant une version pcc acceptant du C ansi et produisant du code pour... PDP-10).
Ne serait-il pas intéressant de s'interfacer avec d'autre backend de compilateur (pas forcément C) qui existe, aprés tout, si tu as le parser (la partie typage, ah, non... ya pas ça ;) et que tu es capable de pondre le bon code intermédiaire...
Je sais que de manière générale, les langages intermédiaires des backends sont trés "proche" du langage compilé au début et qu'il n'est pas toujours facil d'en générer le code, mais je penses que ça pourrait être intéressant à regarder...
De plus, le compilateur C n'est que la partie visible de l'iceberg... il est de nos jours indispensable de disposer au moins d'un compilateur C++...
(et on ne parlera pas de la chain-tools complète...)
On Fri, 3 Oct 2003 12:39:29 +0000 (UTC)
Miod Vallat <miod@online.fr> wrote:
Dans le cas de gcc, tout le monde s'accorde à dire qu'un compilateur
moins obscur, moins bogué, plus rapide et sous licence libre non-GPL
serait le bienvenu. Mais pour l'instant aucun des efforts dans ce sens
n'a donné de résultats concrets. TenDRA est encore loin d'être une
alternative envisageable à gcc, même sur x86 seulement ; et d'autres,
comme lcc ou le compilateur de plan9 ne sont malheureusement pas
libres.
Pour ce qui est de TenDRA, je dirais même que le résultat est très loin
d'être satisfaisant. Juste sur un petit bout code tout petit, le binaire
généré par TenDRA est plus gros et plus lent qu'un binaire généré par gcc
-g (sur mon FreeBSD, sur x86...)
On pourrait reprendre pcc, le moderniser et écrire un optimiseur (après
tout, c'est bien ce qu'un certain Richard S. a fait il y a une
vingtaine d'années...), mais pour l'instant personne ne s'est laissé
tenter(excepté Anders Magnusson, qui a maintenant une version pcc
acceptant du C ansi et produisant du code pour... PDP-10).
Ne serait-il pas intéressant de s'interfacer avec d'autre backend de
compilateur (pas forcément C) qui existe, aprés tout, si tu as le parser
(la partie typage, ah, non... ya pas ça ;) et que tu es capable de
pondre le bon code intermédiaire...
Je sais que de manière générale, les langages intermédiaires des backends
sont trés "proche" du langage compilé au début et qu'il n'est pas toujours
facil d'en générer le code, mais je penses que ça pourrait être
intéressant à regarder...
De plus, le compilateur C n'est que la partie visible de l'iceberg...
il est de nos jours indispensable de disposer au moins d'un compilateur
C++...
(et on ne parlera pas de la chain-tools complète...)
On Fri, 3 Oct 2003 12:39:29 +0000 (UTC) Miod Vallat wrote:
Dans le cas de gcc, tout le monde s'accorde à dire qu'un compilateur moins obscur, moins bogué, plus rapide et sous licence libre non-GPL serait le bienvenu. Mais pour l'instant aucun des efforts dans ce sens n'a donné de résultats concrets. TenDRA est encore loin d'être une alternative envisageable à gcc, même sur x86 seulement ; et d'autres, comme lcc ou le compilateur de plan9 ne sont malheureusement pas libres.
Pour ce qui est de TenDRA, je dirais même que le résultat est très loin d'être satisfaisant. Juste sur un petit bout code tout petit, le binaire généré par TenDRA est plus gros et plus lent qu'un binaire généré par gcc -g (sur mon FreeBSD, sur x86...)
On pourrait reprendre pcc, le moderniser et écrire un optimiseur (après tout, c'est bien ce qu'un certain Richard S. a fait il y a une vingtaine d'années...), mais pour l'instant personne ne s'est laissé tenter(excepté Anders Magnusson, qui a maintenant une version pcc acceptant du C ansi et produisant du code pour... PDP-10).
Ne serait-il pas intéressant de s'interfacer avec d'autre backend de compilateur (pas forcément C) qui existe, aprés tout, si tu as le parser (la partie typage, ah, non... ya pas ça ;) et que tu es capable de pondre le bon code intermédiaire...
Je sais que de manière générale, les langages intermédiaires des backends sont trés "proche" du langage compilé au début et qu'il n'est pas toujours facil d'en générer le code, mais je penses que ça pourrait être intéressant à regarder...
De plus, le compilateur C n'est que la partie visible de l'iceberg... il est de nos jours indispensable de disposer au moins d'un compilateur C++...
(et on ne parlera pas de la chain-tools complète...)