Article View: fr.comp.lang.c
Article #15561Re: alignements struct/tableaux
From: Pierre Maurette
Date: Mon, 19 Sep 2005 05:08
Date: Mon, 19 Sep 2005 05:08
153 lines
6177 bytes
6177 bytes
Pierre Habouzit, le 18/09/2005, a �crit :
[...]
> soit dit en passant du coup, je me demande vraiment � quoi ca sert d'autre
> que de permettre des vues diff�rentes de la m�me structure sous-jacente.
Il semble que l'id�e derri�re l'union soit celle du type variant d'autres
langages. Il faut encapsuler l'union dans une structure qui contient en plus
le renseignement de type.
J'ai fait un bout d'essai pour voir:
<code>
#include <stdio.h>
#include <stdlib.h>
enum {INIT_ERR, VARPRINT_ERR};
const char* service[] = {"Erreur initialisation, type inconnu"
, "Erreur varprint(), type inattendu"}
;
enum Type {ERROR_TYPE, REEL, ENTIER, CHAINE} ;
typedef struct {
enum Type t;
union {
double f;
int i;
const char* s;
};
} variant;
variant initvariant(enum Type t, const char* data)
{
variant ret = {t};
switch(t)
{
case REEL:
ret.f = atof(data);
break;
case ENTIER:
ret.i = atoi(data);
break;
case CHAINE:
ret.s = data;
break;
default:
ret.t = ERROR_TYPE;
ret.s = service[INIT_ERR];
}
return ret;
}
int varprint(variant valeur)
{
int retour;
switch(valeur.t)
{
case REEL:
retour = printf("%f\n", valeur.f);
break;
case ENTIER:
retour = printf("%d\n", valeur.i);
break;
case ERROR_TYPE:
case CHAINE:
retour = puts(valeur.s);
break;
default:
puts(service[VARPRINT_ERR]);
retour = -1;
}
return retour;
}
int main(void)
{
variant a = initvariant(ENTIER, "123")
, b = initvariant(REEL, "3.14159")
, c = initvariant(CHAINE, "C'est � quelle heure qu'on mange ?")
, d = initvariant(12, "�a va pas le faire !")
, e = {ENTIER, 1234}
;
varprint(a);
varprint(b);
varprint(c);
varprint(d);
varprint(e);
e.t = REEL;
varprint(e);
e.t = -1;
varprint(e);
return 0;
}
</code>
J'ai fait un pseudo-constructeur initvariant() pour ne pas risquer l'erreur
illustr�e par:
variant e = {ENTIER, 1234};
Le comportement est ici de convertir 1234 en double, mais il est
compl�tement li� au compilateur donc impr�visible.
Il faudrait comme en C++ pouvoir interdire l'acc�s direct aux donn�es de la
structure et forcer le passage par des constructeurs, getters, setters, etc.
> Parce que si il s'agit juste de pouvoir "embarquer" plusieurs types
> diff�rents, autant utiliser une zone m�moire point�e depuis un void* ...
> ca
> offre � peu pr�s les m�me propri�t�s.
L'union est quand m�me plus souple. D�j�, vous n'avez pas � vous pr�occuper
de trouver le sizeof() maximum, en particulier si vous ajoutez un membre �
votre union, ou si vous aspirez � la portabilit�. Vous allez vite avoir un
truc particuli�rement illisible.
Vous allez transtyper � la hache du void* (ou du char*), il me semble que
vous aurez encore moins de contr�le de type qu'avec l'union.
Il y a �galement � faire de l'arithm�tique de pointeurs sauvage un risque
"psychologique" de pr�sumer � un moment de la taille et de l'implantation
(boutisme) des donn�es.
Ceci dit, je me fais l'avocat de Dieu(*) (esp�rons qu'Il ne sera pas
ingrat), mais je suis plut�t M�phisto sur ce genre de coup.
(*) Emmanuel (de l'h�breu imanu-el ,"Dieu avec nous") est le nom sous lequel
le proph�te Isa�e d�signe, dans l'Ecriture sainte, le Messie ou Sauveur
promis au monde. Saint Emmanuel fut martyr en Orient.
> Sinon *juste pour ma culture personnelle* -- je ne compte certainement pas
> l'utiliser si la norme l'interdit ou ne le sp�cifie pas -- y a-t-il
> vraiment *beaucoup* de compilateurs/architectures o� une struct avec deux
> pointeurs sur le m�me type, ne sont pas align�s pareil que un tableau avec
> deux de ces pointeurs ?
> (sans doute les archis o� les pointeurs ont moins de bits que l'entier le
> plus grand manipulable par le processeur. mais je doute que de telles
> archis soient l�gion ...)
On pourrait peut-�tre penser � des pointeurs dont le sizeof serait de 6 et
l'alignement pr�f�rentiel en modulo 8 par exemple.
> donc reposons la question autrement. si my_type est un type qui repr�sente
> la plus grosse valeur enti�re manipulable par le syst�me (c'est pas
> rigoureux comme d�finition, mais vous comprendrez sans doute mon point).
> est-ce stupide de supposer que :
>
> struct {
> my_type a;
> my_type b;
> }
>
> et my_type c[2] vont �tre align�s pareils ?
Bien entendu, ce que vous faites d�pend du contexte "commercial".
Mais personnellement, s'il y a un gain r�el, je n'h�siterais pas une
seconde. Vous vous couvrez en assertant.
Ici, offsetof(type_struct, b) == sizeof(my_type) et roule ma poule.
Comme �a, vos ferez avancer le schmilblic, en d�couvrant �ventuellement
l'architecture improbable.
Technical Details
Message-ID:
<432e4782$0$27996$626a14ce@news.free.fr>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!feed6.newsreader.com!newsreader.com!news-out1.kabelfoon.nl!newsfeed.kabelfoon.nl!bandi.nntp.kabelfoon.nl!213.239.142.2.MISMATCH!feeder.xsnews.nl!fr.ip.ndsoftware.net!proxad.net!infeed-2.proxad.net!news18-e.free.fr!not-for-mailReferences:
<432c52d5$0$9425$626a14ce@news.free.fr> <mn.8cb87d59c7031bee.15512@YOURBRAnoos.fr> <432c91b5$0$21740$626a14ce@news.free.fr>Show Full Headers
Complete Article Headers
X-Google-Thread: f9822,2ab126dba8e5e645 X-Google-Attributes: gidf9822,public X-Google-Language: FRENCH,ASCII Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!feed6.newsreader.com!newsreader.com!news-out1.kabelfoon.nl!newsfeed.kabelfoon.nl!bandi.nntp.kabelfoon.nl!213.239.142.2.MISMATCH!feeder.xsnews.nl!fr.ip.ndsoftware.net!proxad.net!infeed-2.proxad.net!news18-e.free.fr!not-for-mail From: "Pierre Maurette" <maurettepierre@wanadoo.fr> Newsgroups: fr.comp.lang.c References: <432c52d5$0$9425$626a14ce@news.free.fr> <mn.8cb87d59c7031bee.15512@YOURBRAnoos.fr> <432c91b5$0$21740$626a14ce@news.free.fr> Subject: Re: alignements struct/tableaux Date: Mon, 19 Sep 2005 07:08:49 +0200 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2527 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2527 X-Antivirus: avast! (VPS 0537-2, 16/09/2005), Outbound message X-Antivirus-Status: Clean Lines: 157 Message-ID: <432e4782$0$27996$626a14ce@news.free.fr> Organization: Guest of ProXad - France NNTP-Posting-Date: 19 Sep 2005 07:07:16 MEST NNTP-Posting-Host: 84.7.237.181 X-Trace: 1127106436 news18-e.free.fr 27996 84.7.237.181:2571 X-Complaints-To: abuse@proxad.net