🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: fr.comp.lang.c
Article #15561

Re: alignements struct/tableaux

#15561
From: Pierre Maurette
Date: Mon, 19 Sep 2005 05:08
153 lines
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-mail
References: <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