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

Comment controler la taille d'une strcuture a la compilation

16 réponses
Avatar
FTSoJ
Je souhaite vérifier a la compilation que deux structures ont la même
taille. En cas de différence je souhaite générer une erreur.

Exemple :
Dans un fichier A.c une type T1_user
typedef struct {
int dummy;
int age;
char lastname [128];
char firstname[128];
} T1_user;

Dans un fichier B.c une type T2_Id

typedef struct {
int id;
int age;
char dummy[256]
} T2_id;

Je veux contrôler durant la compilation (et non a l'execution) que
sizeof(T2_id) est equivalent a sizeof(T1_user).


#if sizeof(T2_id) != sizeof(T1_user)
#error "Size of T1_user differ from T2_id, compile abort!"
#endif

Cette solution, ne fonctionne pas sous codewarrior ni GCC.

Comment faire ?

L'exemple est sommaire, en réalité il y a N strcutures (T1 .. Tn)
complexes qui correspondent à de la communication intertache. La
vérification de l'exactitude des sizeof me protege du buffer overflow.

D'avance merci,

- François -

10 réponses

1 2
Avatar
Thierry Boudet
On 2005-05-20, FTSoJ wrote:

Exemple :
Dans un fichier A.c une type T1_user
typedef struct {
int dummy;
int age;
char lastname [128];
char firstname[128];
} T1_user;

Dans un fichier B.c une type T2_Id

typedef struct {
int id;
int age;
char dummy[256]
} T2_id;

Je veux contrôler durant la compilation (et non a l'execution) que
sizeof(T2_id) est equivalent a sizeof(T1_user).



Dans ce cas, pourquoi ne pas coller les struct dans une union ?
Il me semble que ça solutionne le problème.


--
_/°< coin

Avatar
Marc Boyer
FTSoJ wrote:
Je souhaite vérifier a la compilation que deux structures ont la même
taille. En cas de différence je souhaite générer une erreur.

Exemple :
Dans un fichier A.c une type T1_user
typedef struct {
int dummy;
int age;
char lastname [128];
char firstname[128];
} T1_user;

Dans un fichier B.c une type T2_Id

typedef struct {
int id;
int age;
char dummy[256]
} T2_id;

Je veux contrôler durant la compilation (et non a l'execution) que
sizeof(T2_id) est equivalent a sizeof(T1_user).


Si la clarté du message d'erreur t'importe peut, tu peux
essayer:
if (false) { // Pour que le code soit compilé mais aucun code généré
char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
}
avec un petit commentaire dans le code source qui explique
ce que fait cette ligne étrange.

Tant qu'à être parano, à ta place, je vérifierais que les offsetof
de age lastname/dummy correspondent bien à ce que tu veux.

#if sizeof(T2_id) != sizeof(T1_user)
#error "Size of T1_user differ from T2_id, compile abort!"
#endif

Cette solution, ne fonctionne pas sous codewarrior ni GCC.


Normal, le préprocesseur ne connait pas sizeof.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.

Avatar
Antoine Leca
En <news:428d7698$0$839$, FTSoJ va escriure:
Je souhaite vérifier a la compilation que deux structures ont la même
taille. En cas de différence je souhaite générer une erreur.


int tableau_ne_servant_a_rien[sizeof(T1_user) == sizeof(T2_id)] = {0};


Antoine

Avatar
Emmanuel Delahaye
FTSoJ wrote on 20/05/05 :
Je souhaite vérifier a la compilation que deux structures ont la même taille.
En cas de différence je souhaite générer une erreur.


Pas possible de manière standard. Si tu as ce genre de besoin, c'est à
mon avis que tu as un problème de conception...

Par contre, ça peut se tester à l'exécution avec un simple assert().

Exemple :
Dans un fichier A.c une type T1_user
typedef struct {
int dummy;
int age;
char lastname [128];
char firstname[128];
} T1_user;

Dans un fichier B.c une type T2_Id

typedef struct {
int id;
int age;
char dummy[256]
} T2_id;

Je veux contrôler durant la compilation (et non a l'execution) que
sizeof(T2_id) est equivalent a sizeof(T1_user).


C'est idiot. Soit tu fais une seule structure, soit tu fais une union
des deux.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

.sig under repair

Avatar
Emmanuel Delahaye
Marc Boyer wrote on 20/05/05 :
Si la clarté du message d'erreur t'importe peut, tu peux
essayer:
if (false) { // Pour que le code soit compilé mais aucun code généré
char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
}
avec un petit commentaire dans le code source qui explique
ce que fait cette ligne étrange.


Asctucieux.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.

Avatar
Marc Boyer
In article , Emmanuel Delahaye wrote:
Marc Boyer wrote on 20/05/05 :
Si la clarté du message d'erreur t'importe peut, tu peux
essayer:
if (false) { // Pour que le code soit compilé mais aucun code généré
char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
}
avec un petit commentaire dans le code source qui explique
ce que fait cette ligne étrange.


Asctucieux.


J'ai pris l'idée dans un bouquin sur les templates C++.
"Modern C++ programming" de tête.
Une petite macro par dessus, et on peut écrire
STATIC_ASSERT(sizeof(T1_user)==sizeof(T2_id));

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.


Avatar
Gabriel Dos Reis
"Emmanuel Delahaye" writes:

| Marc Boyer wrote on 20/05/05 :
| > Si la clarté du message d'erreur t'importe peut, tu peux
| > essayer:
| > if (false) { // Pour que le code soit compilé mais aucun code généré
| > char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
| > }
| > avec un petit commentaire dans le code source qui explique
| > ce que fait cette ligne étrange.
|
| Asctucieux.

C'est une pratique répandue dans la communauté C++. D'après ce
que je vois, quelqu'un l'a mis dans un bouquin sans préciser que
c'est une pratique courante, i.e. qu'il n'en est pas l'auteur.

Note cependant, que GNU C autorise les tableaux de taille zéro, donc
tu n'aurais pas toujours l'erreur.

-- Gaby
Avatar
Patrick 'Zener' Brunet
Bonjour.

"Emmanuel Delahaye" writes:

Marc Boyer wrote on 20/05/05 :
Si la clarté du message d'erreur t'importe peut, tu peux
essayer:
if (false) { // Pour que le code soit compilé mais aucun code généré
char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
}
avec un petit commentaire dans le code source qui explique
ce que fait cette ligne étrange.


Asctucieux.


C'est une pratique répandue dans la communauté C++. D'après ce
que je vois, quelqu'un l'a mis dans un bouquin sans préciser que
c'est une pratique courante, i.e. qu'il n'en est pas l'auteur.

Note cependant, que GNU C autorise les tableaux de taille zéro, donc
tu n'aurais pas toujours l'erreur.



Et en faisant :

if( 0)
{
char SameSizeNeeded[2 * (sizeof(T1_user)==sizeof(T2_id)) - 1];
}

Là par contre ça devrait devenir imparable... Aucun compilo ne peut tolérer
l'anti-matière AMHA.

Cordialement,

--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/



Avatar
Gabriel Dos Reis
"Patrick 'Zener' Brunet" writes:

| Bonjour.
|
| > "Emmanuel Delahaye" writes:
| >
| >> Marc Boyer wrote on 20/05/05 :
| >>> Si la clarté du message d'erreur t'importe peut, tu peux
| >>> essayer:
| >>> if (false) { // Pour que le code soit compilé mais aucun code généré
| >>> char TestEqualityT1_T2[sizeof(T1_user)==sizeof(T2_id)];
| >>> }
| >>> avec un petit commentaire dans le code source qui explique
| >>> ce que fait cette ligne étrange.
| >>
| >> Asctucieux.
| >
| > C'est une pratique répandue dans la communauté C++. D'après ce
| > que je vois, quelqu'un l'a mis dans un bouquin sans préciser que
| > c'est une pratique courante, i.e. qu'il n'en est pas l'auteur.
| >
| > Note cependant, que GNU C autorise les tableaux de taille zéro, donc
| > tu n'aurais pas toujours l'erreur.
| >
|
| Et en faisant :
|
| if( 0)
| {
| char SameSizeNeeded[2 * (sizeof(T1_user)==sizeof(T2_id)) - 1];
| }
|
| Là par contre ça devrait devenir imparable...

C'est-à-dire ?

-- Gaby
Avatar
Emmanuel Delahaye
Gabriel Dos Reis wrote on 21/05/05 :
Et en faisant :

if( 0)
{
char SameSizeNeeded[2 * (sizeof(T1_user)==sizeof(T2_id)) - 1];
}

Là par contre ça devrait devenir imparable...


C'est-à-dire ?


Une taille de (sizeof)-1 est une sorte d'infini... Ca ne devrait jamais
compiler...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"


1 2