116 votes

Comment utiliser "sizeof" dans une macro de préprocesseur?

Est-il de toute façon à utiliser un sizeof dans une macro préprocesseur ?

Par exemple, il y a eu une tonne de situations au cours des années où j'ai voulu faire quelque chose comme:

#if sizeof(someThing) != PAGE_SIZE
#error Data structure doesn't match page size
#endif

La chose exacte que je suis ici de vérification est complètement constitué le point est, j'ai souvent envie de mettre dans ces types de (de la taille ou de l'alignement) des contrôles de compilation afin de se prémunir contre quelqu'un de la modification d'une structure de données qui pourrait perdre l'alignement ou re-taille, les choses qui serait casser.

Inutile de dire que je ne semble pas être en mesure d'utiliser un sizeof de la manière décrite ci-dessus.

87voto

nevermind Points 339

Si vous voulez juste pour obtenir une erreur de compilation lors de l' sizeof(something) n'est pas ce que vous attendez, vous pouvez utiliser la macro suivante:

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

Cet article explique comment ça fonctionne: http://scaryreasoner.wordpress.com/2009/02/28/checking-sizeof-at-compile-time/


En C++11, vous pouvez utiliser static_assert. Ou sur les anciens MS compilateurs vous pouvez utiliser C_ASSERT macro (nécessite l' #include <windows.h>), qui utilise le truc similaire est décrit ci-dessus.

74voto

James McNellis Points 193607

Est-il de toute façon à utiliser un "sizeof" dans un pré-processeur de macro?

Pas de. Les directives conditionnelles prendre un ensemble restreint d'expressions conditionnelles; sizeof est l'une des choses à ne pas autorisées.

Prétraitement des directives sont évalués avant que la source est analysé (au moins conceptuellement), donc il n'y a pas tout les types des variables ou encore pour obtenir leur taille.

Cependant, il existe des techniques pour arriver au moment de la compilation des assertions en C (par exemple, voir cette page).

4voto

Serhio Points 1

Qu'en est-il de la prochaine macro:

 /* 
 * Simple compile time assertion.
 * Example: CT_ASSERT(sizeof foo <= 16, foo_can_not_exceed_16_bytes);
 */
#define CT_ASSERT(exp, message_identifier) \
    struct compile_time_assertion { \
        char message_identifier : 8 + !(exp); \
    }
 

Par exemple, dans le commentaire, MSVC dit quelque chose comme:

test.c (42): erreur C2034: 'foo_can_not_exceed_16_bytes': type du champ de bits trop petit pour le nombre de bits

1voto

À titre de référence pour cette discussion, je signale que certains compilateurs obtiennent le temps avant processeur de sizeof ().

La réponse de JamesMcNellis est correcte, mais certains compilateurs respectent cette limitation (cela viole probablement les règles strictes).

En guise de cas, je me réfère au compilateur IAR C (probablement le premier pour la programmation professionnelle de microcontrôleurs / embarqués).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X