Comment controler la taille d'une strcuture a la compilation
16 réponses
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.
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
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.
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.
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.
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
En <news:428d7698$0$839$8fcfb975@news.wanadoo.fr>, 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};
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
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.
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.
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.
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.
In article <mn.a40b7d551b1ee4ca.15512@YOURBRAnoos.fr>, 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.
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.
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.
| 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.
| 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
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.
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.
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.
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 ***************************************/
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...
| Bonjour.
|
| > "Emmanuel Delahaye" <emdel@YOURBRAnoos.fr> 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...
| 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...