tableau à 0 élément

Le
Thomas Nemeth
Bonjour,

Je parcourais un site web ce matin et je suis tombé sur un extrait
des nouveautés dans un noyau unix très répandu :

struct sg_ring
{
struct list_head list;
unsigned int num, max;
struct scatterlist sg[0];
};

Je me demande, dans cette structure, ce que signifie ce tableau
à 0 élément Le K&R spécifie que, je cite :
"Dans une déclaration T D où D est de la forme
D1[expression-constante/opt/]
[]
Si une expression constante est présente, elle doit être du type
entier et de valeur supérieure à 0."

Je suis perplexe Quelqu'un a-t-il une solution/explication ?


Thomas.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #1002239
Thomas Nemeth
Bonjour,

Je parcourais un site web ce matin et je suis tombé sur un extrait
des nouveautés dans un noyau unix très répandu :

struct sg_ring
{
struct list_head list;
unsigned int num, max;
struct scatterlist sg[0];
};

Je me demande, dans cette structure, ce que signifie ce tableau
à 0 élément... Le K&R spécifie que, je cite :
"Dans une déclaration T D où D est de la forme
D1[expression-constante/opt/]
[...]
Si une expression constante est présente, elle doit être du type
entier et de valeur supérieure à 0."

Je suis perplexe... Quelqu'un a-t-il une solution/explication ?


C'est un vieux truc -- extension de gcc, disponible en C99 sous une autre
forme -- permettant d'allouer un tableau de taille variable apres une
structure.

struct sg_ring* ptr = malloc(sizeof(struct sg_ring) + nb_elem*sizeof(struct
scatterlist));

puis on utilise ptr->sg[4]

On l'utilise aussi avec un tableau de taille 1, mais l'allocation est un
peu plus compliquee:

struct sg_ring* ptr = malloc(sizeof(struct sg_ring) + (nb_elem-1)*sizeof(struct
scatterlist));



--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Thierry B.
Le #1002238
--{ Thomas Nemeth a plopé ceci: }--

Bonjour,

Salut jeune homme.


struct sg_ring
{
struct list_head list;
unsigned int num, max;
struct scatterlist sg[0];
};


C'est un bon vieux hack bien goret, (et extrèmement confortable)
qui permet de construire des "structures à taille variable".
En gros, quand tu as un ectoplasme de ce genre à utiliser, tu
le malloques (ou réalloques, hein) avec une taille egale à:

( sizeof(ta_structure) + (sizeof(ton_machin) * NBRE_ton_machine) )

Par contre, je l'ai toujours pratiqué avec, dans la déclaration,
un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.

Je suis perplexe... Quelqu'un a-t-il une solution/explication ?


Solution: utiliser un _vrai_ langage (Lisp, oCaml, Brainf*ck)
Explication: continuer comme ça, c'est pas si mauvais...

tTh, goret-codeur.

--
"Ubuntu" -- an African word, meaning "Slackware is too hard for me".

diablo
Le #1002077
Solution: utiliser un _vrai_ langage (Lisp, oCaml, Brainf*ck)


Parce que selon toi, le Brainf*ck a plus le statut de langage que le C ? :/


--
-uTb#`diablo PWed by GNU/Linux Debian on Diablo

thib´
Le #1002076
diablo wrote:
Solution: utiliser un _vrai_ langage (Lisp, oCaml, Brainf*ck)


Parce que selon toi, le Brainf*ck a plus le statut de langage que le C ? :/


Mon petit doigt me dit qu'il s'agissait d'une impulsion émotionnelle à
volonté de propagation spécifiée sous le nom d'Humour, sous-catégorie
Ironie.

Cela dit, c'est pas un guwu, mon doigt.

-thib´


diablo
Le #1002075
Mon petit doigt me dit qu'il s'agissait d'une impulsion émotionnelle à
volonté de propagation spécifiée sous le nom d'Humour, sous-catégorie
Ironie.


Mon second degré a du mal ce soir ;)

--
-uTb#`diablo PWed by GNU/Linux Debian on Diablo

espie
Le #1002074
In article Thierry B.
Par contre, je l'ai toujours pratiqué avec, dans la déclaration,
un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.


Avec la taille du tableau a 1, ca n'a rien de dangereux, et les compilo
ne ralent pas.

Les regles du C sont explicitement concues pour que ca fonctionne.

Thomas Nemeth
Le #1002073
Marc Espie a tapoté :

In article Thierry B.
Par contre, je l'ai toujours pratiqué avec, dans la déclaration,
un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.


Avec la taille du tableau a 1, ca n'a rien de dangereux, et les
compilo ne ralent pas.


Je pense que Thierry parlait dans le cas du tableau à 0
éléments dans sa dernière phrase.


Les regles du C sont explicitement concues pour que ca fonctionne.


Ok, merci à tous, je me coucherai moins con ce soir :)

Ne serait-ce pas intéressant de mettre cette entrée dans la FAQ ?
Je l'y avait cherchée avant sans succès et comme la FAQ m'a déjà
bien servi dans le passé, je pense que ça pourrait être utile aux
autres.


Thomas.


Marc Boyer
Le #1002072
On 2008-01-10, Thierry B.
--{ Thomas Nemeth a plopé ceci: }--

Bonjour,

Salut jeune homme.


struct sg_ring
{
struct list_head list;
unsigned int num, max;
struct scatterlist sg[0];
};


C'est un bon vieux hack bien goret, (et extrèmement confortable)
qui permet de construire des "structures à taille variable".
En gros, quand tu as un ectoplasme de ce genre à utiliser, tu
le malloques (ou réalloques, hein) avec une taille egale à:

( sizeof(ta_structure) + (sizeof(ton_machin) * NBRE_ton_machine) )

Par contre, je l'ai toujours pratiqué avec, dans la déclaration,
un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.


Tellement confortable que le principe a été introduit dans C99,
avec un syntaxe un peu différente ([] au lieu de [0]).

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)


Antoine Leca
Le #1002071
En news:fm5vpe$8k9$, Marc Espie va escriure:
In article
Par contre, je l'ai toujours pratiqué avec, dans la déclaration,
un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.


Avec la taille du tableau a 1, ca n'a rien de dangereux, et les
compilo ne ralent pas.

Les regles du C sont explicitement concues pour que ca fonctionne.


Je crois que techniquement (pédantiquement, interprétation officielle,
non-qosher comme il dit si bien), ce n'est pas completement clair (si tu
alloues plus d'un élément), parce que les déréférencements se feront au-delà
des limites du type. Cf.
http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_051.html
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n791.htm

Et ce, alors même que la rédaction de 6.3.6 (C90, 6.5.6 en C99 avec
essentiellement le même texte) est suffisament fine, en faisant référence à
l'objet (sous-jaçent, donc ce qui est alloué) plutôt qu'au tableau et encore
moins à son type (donc sa dimension).


Maintenant, c'est sûr que cela marche sur (quasiment) tous les compilos; le
seul cas où je pressens un problème, ce serait d'utiliser _hmalloc()
(allocation d'objets de plus de 64K en environnement DOS 16 bits), avec le
tableau déclaré __huge, mais qui serait mal aligné pour passer la frontière
de paragraphe (ce qui n'est pas un problème avec une taille de 1).
Un cas plus qu'exotique, qui ne fait pas partie de la stricte conformité,
qui me paraît relever de la catégorie « bogue du compilo/_hmalloc() », qui
est (heureusement) réservé aujourd'hui à l'étude par les spécialistes de
tetracapillossection (genre comp.std.c), et dont l'utilisation (celle des
pointeurs __huge) tombe de toutes manières dans le cadre du « dangereux » !


Sur le fait que ce soit dangereux, je ne vois pas pourquoi ce serait plus
dangereux que d'utiliser des pointeurs ou l'allocation dynamique de mémoire.
Par exemple, utiliser sizeof() sur le membre tableau ou la structure serait
une erreur, mais de toute manière utiliser sizeof() sur des structures
dynamiques, c'est « dangereux » (et même avec les VLA, je ne préfère pas,
certes la norme dit ce qu'elle dit, mais les possibilités de bogues de
compilateur sont réelles.)


Antoine


Thierry B.
Le #1002068
--{ Marc Espie a plopé ceci: }--

un nombre d'éléments à 1, pour éviter les roumaigailles de certains
compilateurs. Voilà, c'est confortable, non_casher et dangeureux.


Avec la taille du tableau a 1, ca n'a rien de dangereux, et les compilo
ne ralent pas.


Par "dangeureux", je voulais dire que la moindre erreur dans la
traçabilité du nombre d'éléments (ré)alloués dans la partie à
taille variable est parfois épuisante à débugger. Sans compter
les pointeurs qui apprennent la danse du ventre :)

Les regles du C sont explicitement concues pour que ca fonctionne.


_Tout_ fonctionne en C, mais parfois on ne sait plus ce que ça fait.


--
Sur le stand MS il faudrait tester 850*77.1 dans excel 2008
Ca fait quoi ?

Dans la version Windows (Excel 2007), ça donne 100000 au lieu de 65535.

--{ Microsoft arrondit les angles }--


Publicité
Poster une réponse
Anonyme