OVH Cloud OVH Cloud

Les structures à taille variables sont elles portables ?

27 réponses
Avatar
Luc de Bauprois
Bonjour

Le code suivant est il portable :

-----------------------------------------------------------------------
struc machin
{
// Autres memebre virés pour plus de clarté

char string[1]; // dernier membre de la struct
};

puis faire des allocation du style

struct machin *s = (struct machin *)malloc( sizeof( struct machin) +
strlen(chaine));

.../...

strcpy( s->chaine, chaine );
-----------------------------------------------------------------------

Ca alloue des struct de taille variable, en laissant de la place "à la
fin" pour écrire le contenu dans la châine.

Est ce "propre" ? Normalisé ? Portable ? Ou y a t'il des effets de bord
pervers qui vont provoquer un merdier indemerdable plus tard ?

Merci

7 réponses

1 2 3
Avatar
Laurent Deniau
Eric Levenez wrote:
Le 7/11/06 10:35, dans <eipk1d$92h$, « Laurent Deniau »


Eric Levenez wrote:

Le 6/11/06 19:36, dans <einvba$lm8$, « Laurent Deniau »


// interface.h
struct T {


Je n'utilise les majuscules que pour les noms pour le préprocesseur.


Il se trouve que c'est justement un nom pour le preprocesseur, ce code
est extrait d'une interface 'generique'.



Moins on utilise le préprocesseur pour les defines ou macros, mieux cela
vaut.


Ah? Et que peut-on utiliser d'autre pour les macros? Et en quoi faut-il
eviter le preprocesseur?

J'ai poste cette interface recemment sur comp.lang.c dans le thread
'Extremly fast dinamic array implementation'



Et alors ?


Alors en le lisant, tu aurais eu les reponses a tes questions.

size_t n;
#if ISO_C99
char t[];
#elif ISO_C89


ISO_C99 et ISO_C89 ne sont pas standard et même avec un compilateur conforme
cela ne donnera rien. Tu as quelque chose contre __STD_VERSION__ ?


Oui, parce que je ne me souvient jamais du mois. J'ai toujours un
fichier de setup qqpart qui detecte le niveau d'ISO compatibilite du
compilateur et le met dans ISO_C et je le compare au valeur du standard
mise dans ISO_C89, ISO_C94, ISO_C99.

Mais j'aurais du ecrire ISO_C >= ISO_C99 etc...



Tu aurais pu, mais même ainsi ISO_C n'est pas défini et non standard.


Ok vu que tu as l'air de vouloir la jouer capillotracte, voici les
macros qui manquent et qui sont dans mon setup.h:

#ifdef __STDC_VERSION__
#define ISO_C __STDC_VERSION__
#else
#define ISO_C ISO_C90
#endif

#define ISO_C90 199000L // ISO/IEC 9899:1990
#define ISO_C95 199409L // ISO/IEC 9899:199409
#define ISO_C99 199901L // ISO/IEC 9899:199901

Mais ceci ne suffira pas a faire compiler ni mon code, ni ton code.

char t[1];
#elif __GNUC__



Dès que l'on utilise une spécificité de GCC, "c'est mal".


Ah? Qu'est ce que tu as contre gcc?



Quand on utilise ses "extensions" on se limite et on essaye d'imposer aux
autres ce compilateur.


En quoi le code que j'ai fourni est 'limite' a gcc. J'ai l'impression
que tu aimes isoler un point de son contexte, histoire d'alimenter la
contestation.

char t[0];
#else
#error not supported


Ou mauvais define :-)


? quel define?



Voir plus haut.
idem.


#endif
};

// implementation.c
struct T *tab = malloc(offsetof(struct T, t) + n*sizeof *tab->t);

Peux-tu reecrire cette ligne uniquement avec sizeof pour voir si c'est
plus joli?


Oui, sans problème :

struct t {
size_t n;
char t[];
};

struct t *tab = malloc(sizeof *tab + n * sizeof *tab->t);


gcc -stdÈ9 -pedantic -W -Wall ton_exemple.c

ne compile pas.



On peut toujours lancer le compilateur avec des options imposant les
anciennes normes. Cela apporte quoi au débat ?


La portabilite. Peux-tu me citer un compilateur C 100% conforme a C99?
En attendant, C89 ou une version 'restreinte' de C99 reste a l'ordre du
jour quand on parle de portabilite.

a+, ld.




Avatar
Pierre Maurette
[...]
Ah? Et que peut-on utiliser d'autre pour les macros?


Du vin blanc ? Et pour les attraper, boëter à l'encornet ?

--
Pierre Maurette

Avatar
Harpo
Pierre Maurette wrote:

[...]
Ah? Et que peut-on utiliser d'autre pour les macros?


Du vin blanc ? Et pour les attraper, boëter à l'encornet ?


Une lanière de macro coupée en triangle effilé, c'est encore meilleur.
Ce sont des macros recursifs.

--
http://patrick.davalan.free.fr/


Avatar
Eric Levenez
Le 7/11/06 13:17, dans <eipti2$dcq$, « Laurent Deniau »
a écrit :

Eric Levenez wrote:

Moins on utilise le préprocesseur pour les defines ou macros, mieux cela
vaut.


Ah? Et que peut-on utiliser d'autre pour les macros? Et en quoi faut-il
eviter le preprocesseur?


Parce que beaucoup l'utilisent mal et cela entraîne de nombreux effets de
bord. Mais ne n'ai pas dit qu'il ne fallait pas utiliser les macros, il faut
juste les utiliser le moins possible. Une fonction inline, par exemple, fait
souvent le même travail en ajoutant de la lisibilité.

J'ai poste cette interface recemment sur comp.lang.c dans le thread
'Extremly fast dinamic array implementation'


Et alors ?


Alors en le lisant, tu aurais eu les reponses a tes questions.


Je n'ai pas de question.

Tu aurais pu, mais même ainsi ISO_C n'est pas défini et non standard.


Ok vu que tu as l'air de vouloir la jouer capillotracte, voici les
macros qui manquent et qui sont dans mon setup.h:


Si tu postes du code, alors essaye de poster un code qui ne requiert pas un
include propriétaire :-)

Quand on utilise ses "extensions" on se limite et on essaye d'imposer aux
autres ce compilateur.


En quoi le code que j'ai fourni est 'limite' a gcc.


Les extensions gcc ne sont pas portables par définition et l'on traîne du
code qui ne compile que sur gcc à cause de ces pratiques.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



Avatar
Pierre Maurette
Le 7/11/06 13:17, dans <eipti2$dcq$, « Laurent Deniau »
[...]

Ah? Et que peut-on utiliser d'autre pour les macros? Et en quoi faut-il
eviter le preprocesseur?


Parce que beaucoup l'utilisent mal et cela entraîne de nombreux effets de
bord.


Ce qui est vrai globalement du langage C. Dont il faut donc
déconseiller l'usage.

--
Pierre Maurette


Avatar
Eric Levenez
Le 7/11/06 18:31, dans , « Pierre
Maurette » a écrit :

Le 7/11/06 13:17, dans <eipti2$dcq$, « Laurent Deniau »
[...]

Ah? Et que peut-on utiliser d'autre pour les macros? Et en quoi faut-il
eviter le preprocesseur?


Parce que beaucoup l'utilisent mal et cela entraîne de nombreux effets de
bord.


Ce qui est vrai globalement du langage C.


Il ne faut pas pousser quand même.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



Avatar
Laurent Deniau
Eric Levenez wrote:
Le 7/11/06 13:17, dans <eipti2$dcq$, « Laurent Deniau »


Eric Levenez wrote:

Moins on utilise le préprocesseur pour les defines ou macros, mieux cela
vaut.


Ah? Et que peut-on utiliser d'autre pour les macros? Et en quoi faut-il
eviter le preprocesseur?



Parce que beaucoup l'utilisent mal et cela entraîne de nombreux effets de
bord. Mais ne n'ai pas dit qu'il ne fallait pas utiliser les macros, il faut
juste les utiliser le moins possible. Une fonction inline, par exemple, fait
souvent le même travail en ajoutant de la lisibilité.


Dans COS (C Objet System), j'ai environ 800 macros (toutes ne sont pas
utilisee dans une meme TU) et aucune ne peut etre remplacee par une
fonction inline. Je fais quoi, je jette tout?

Ok vu que tu as l'air de vouloir la jouer capillotracte, voici les
macros qui manquent et qui sont dans mon setup.h:



Si tu postes du code, alors essaye de poster un code qui ne requiert pas un
include propriétaire :-)


J'avais pris des noms de macros relativement explicite pour eviter de
mettre les defines. Il me semble qu'un minimum de bon sens permettait de
comprendre l'intention. Comme je l'avais souligne, c'etait un extrait de
code. Un code qui compile aurait demander au minimum un include
supplementaire, dans mon code comme dans le tient.

Quand on utilise ses "extensions" on se limite et on essaye d'imposer aux
autres ce compilateur.


En quoi le code que j'ai fourni est 'limite' a gcc.



Les extensions gcc ne sont pas portables par définition et l'on traîne du
code qui ne compile que sur gcc à cause de ces pratiques.


Avant de crier aux extensions pas portables, et en supposant que les
macros on la semantique attendue, voyons quel compilateur utilisera au
final l'extension de gcc? Reponse: gcc en mode traditionnel et gcc est
compatible avec gcc, enfin presque ;-)

a+, ld.



1 2 3