Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Structures imbriquées / Structure anonyme

8 réponses
Avatar
pini_os
J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser anonyme.
J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)


Question :
1) Le changement que je propose est-il permis par la norme ?
2) Si oui, s'agit-il d'un bug de GCC ?

Merci d'avance

8 réponses

Avatar
Horst Kraemer
On 10 Apr 2004 10:45:53 -0700, (Pini) wrote:

J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser anonyme.
J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)


Question :
1) Le changement que je propose est-il permis par la norme ?


Enlever le 'tag' t est permis mais alors 'field' n'est pas permis
comme opérande de l'opérateur 'sizeof'. L'opérande de sizeof doit
avoir la forme (type) ou elle doit être une expression qui désigne une
valeur ou un objet. Le nom d'un membre d'une structure n'est ni l'un
ni l'autre.

struct
{
int i;
char c[sizeof i];
};

ne serait permis non plus parce que 'i' ne désigne ni une valeur ni un
objet. 'i' n'a pas de sens dans ce contexte,

--
Horst

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', (Pini) wrote:

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser
anonyme. J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)

Question :
1) Le changement que je propose est-il permis par la norme ?


Non. Une structure anonyme n'étant pas déréférençable, elle n'a pas de
taille.

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Horst Kraemer
On 11 Apr 2004 20:29:33 GMT, Emmanuel Delahaye
wrote:

In 'fr.comp.lang.c', (Pini) wrote:

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser
anonyme. J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)

Question :
1) Le changement que je propose est-il permis par la norme ?


Non. Une structure anonyme n'étant pas déréférençable, elle n'a pas de
taille.


#include <stdio.h>

int main()
{

printf("%dn, (int) sizeof (struct {int i,j;}) );
return 0;
}

--
Horst


Avatar
Stephane Legras-Decussy
"Horst Kraemer" a écrit dans le message de news:

printf("%dn, (int) sizeof (struct {int i,j;}) );


ça ne compile pas, il manque un " ... ;-)

Avatar
Régis Troadec
"Horst Kraemer" a écrit dans le message de
news:

Salut,

On 10 Apr 2004 10:45:53 -0700, (Pini) wrote:

J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser
anonyme.


J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)


Question :
1) Le changement que je propose est-il permis par la norme ?


Enlever le 'tag' t est permis mais alors 'field' n'est pas permis
comme opérande de l'opérateur 'sizeof'. L'opérande de sizeof doit
avoir la forme (type) ou elle doit être une expression qui désigne une
valeur ou un objet. Le nom d'un membre d'une structure n'est ni l'un
ni l'autre.

struct
{
int i;
char c[sizeof i];
};

ne serait permis non plus parce que 'i' ne désigne ni une valeur ni un
objet. 'i' n'a pas de sens dans ce contexte,


Gros dilemme intéressant ou grosse bêtise vu l'heure a laquelle je poste, je
pose la question suivante :

[avant-propos question]
La définition d'un objet en C est une zone de mémoire allouée et nommée dans
l'environnement d'exécution. Je comprends également que lorsqu'on se trouve
entre les accolades, la structure en question est incomplète et n'est pas un
objet. Ceci dit, aucun membre de structure ne peut être de type incomplet
(en excluant l'autoréférence par l'intermédiaire d'un pointeur) et je n'ai
rien trouvé vraiment d'explicite disant qu'un membre de structure n'est pas
un objet, à part en combinant ce que définit la grammaire du langage
concernant les structures et la definition de lvalue, qui veulent qu'au sein
d'une structure <code> struct { int i; }s; s.i = 3; </code>, s.i est par
exemple une lvalue. J'en déduis donc que l'objet est s.i (donc s) et non i.
J'en viens à l'opérateur sizeof, que l'on peut normalement appliquer a un
opérande qui n'a pas de type incomplet, sizeof(s.i) est correct et retourne
le nombre de bytes pour un int pour cet exemple.

[question]
Maintenant, pour ce qui est compris entre les accolades, où dans cet espace
de noms, les membres ne sont pas de types incomplets, n'est-ce pas une
*hérésie* de ne pas pouvoir utiliser l'opérateur sizeof avec pour opérandes
les noms de ces membres ?
Si non pourquoi ? (par souci de simplicité pour écrire les compilateurs,
autre chose... ?)

Regis

--
Horst




Avatar
Régis Troadec
"Pini" a écrit dans le message de
news:
J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser
anonyme.


Je vois une solution :

typedef struct st_s
{
struct
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof( struct {int a,b,c; struct st_s* next; int
state[108];} )];
}mystruct;

Regis

Avatar
Horst Kraemer
On Mon, 12 Apr 2004 02:23:50 +0200, "Régis Troadec"
wrote:


"Horst Kraemer" a écrit dans le message de
news:

Salut,

On 10 Apr 2004 10:45:53 -0700, (Pini) wrote:

J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;

mais je voudrais pouvoir ne pas nommer la structure "t" et la laisser
anonyme.


J'ai donc remplacé la définition de "stack" par :

char stack[4096 - sizeof(field)];

et j'ai retiré le "t" du nom de la structure interne.

gcc (version 3.2.2) donne l'erreur suivante :

`field' undeclared here (not in a function)


Question :
1) Le changement que je propose est-il permis par la norme ?


Enlever le 'tag' t est permis mais alors 'field' n'est pas permis
comme opérande de l'opérateur 'sizeof'. L'opérande de sizeof doit
avoir la forme (type) ou elle doit être une expression qui désigne une
valeur ou un objet. Le nom d'un membre d'une structure n'est ni l'un
ni l'autre.

struct
{
int i;
char c[sizeof i];
};

ne serait permis non plus parce que 'i' ne désigne ni une valeur ni un
objet. 'i' n'a pas de sens dans ce contexte,


Gros dilemme intéressant ou grosse bêtise vu l'heure a laquelle je poste, je
pose la question suivante :

[avant-propos question]
La définition d'un objet en C est une zone de mémoire allouée et nommée dans
l'environnement d'exécution. Je comprends également que lorsqu'on se trouve
entre les accolades, la structure en question est incomplète et n'est pas un
objet.


La structure anonyme est compléte après l'accolade } qui termine *sa*
définition.

Mais une structure est un *type*. Un objet (de ce type) est une région
de la mémoire à laquelle ce type est attribuée. Une variable du type
struct foo serait un *objet*.

Ceci dit, aucun membre de structure ne peut être de type incomplet
(en excluant l'autoréférence par l'intermédiaire d'un pointeur) et je n'ai
rien trouvé vraiment d'explicite disant qu'un membre de structure n'est pas
un objet, à part en combinant ce que définit la grammaire du langage
concernant les structures et la definition de lvalue, qui veulent qu'au sein
d'une structure <code> struct { int i; }s; s.i = 3; </code>, s.i est par
exemple une lvalue. J'en déduis donc que l'objet est s.i (donc s) et non i.


Oui. s est un objet et s,i est un objet. 'i' ne veut rien dire dans le
contexte de structure (on n'est pas en C++).

J'en viens à l'opérateur sizeof, que l'on peut normalement appliquer a un
opérande qui n'a pas de type incomplet, sizeof(s.i) est correct et retourne
le nombre de bytes pour un int pour cet exemple.

[question]
Maintenant, pour ce qui est compris entre les accolades, où dans cet espace
de noms, les membres ne sont pas de types incomplets, n'est-ce pas une
*hérésie* de ne pas pouvoir utiliser l'opérateur sizeof avec pour opérandes
les noms de ces membres ?


Le noms de membre sont ni des types ni des objets...

Si non pourquoi ? (par souci de simplicité pour écrire les compilateurs,
autre chose... ?)


Parce que la norme le dit ;-)

--
Horst



Avatar
Antoine Leca
En , Pini va escriure:
J'ai la définition suivante :

typedef struct st_s
{
struct t
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096 - sizeof(struct t)];
}mystruct;


<HP>
Cas typique d'emploi d'une nouvelle fonctionnalité du C: l'union:
typedef union st_s
{
struct
{
int a;
int b;
int c;
struct st_s* next;
int state[108];
}field;
char stack[4096];
}mystruct;
</HP>


Antoine