top of page
Rechercher

sizeof et compilation

  • Photo du rédacteur: Renaud Jordi
    Renaud Jordi
  • 8 nov. 2023
  • 2 min de lecture

Aujourd’hui, astuce de programmation en C. Détournement de sizeof à la compilation ;)


sizeof n'est pas une fonction, mais un opérateur (inhérent au langage) qui permet de connaitre la taille d’une donnée, ou d’une structure.

Comme le langage C ne permet pas de créer dynamiquement de nouveaux types, toutes les données sont déjà typées au moment de la compilation.

De plus, en fonction de la cible, certains types peuvent varier (comme un int en 16 ou 32 bits), certaines structures peuvent utiliser le padding pour l’alignement mémoire imposé par les architectures.


Ces contraintes sont connues par le compilateur et sont calculables à la compilation.

Beaucoup de compilateurs (mas pas tous) permettent l’utilisation du sizeof au préprocesseur, comme avec l’exemple ci-dessous :

#if sizeof(data) > MAX_SIZE
#error data can't be allocated
#endif

Cela permet une vérification préalable, mais nous verrons ici, une méthode plus élégante et compatible avec 100% des compilateurs.

Voyons en détail :

L’opérateur sizeof retourne un entier non signé, de type size_t, qui peut être testée et comparée à une valeur connue au moment de la compilation.

L’usage du test ternaire est idéal dans le cas suivant

int _onlyfortest[sizeof(data) > MAX_SIZE ? -1 : 1];

Le tableau _onlyfortest aura une longueur de 1 si la taille de la data est valide, sinon un tableau de longueur -1 sera déclaré invalide et le compilateur signalera une erreur sur cette ligne.

L’inconvénient ici est l’allocation d’un tableau de 1 élément qui ne sert à rien, dans le cas où le test réussi.


Voyons comment y remédier

Vous connaissez sûrement la déclaration d’une structure de champ de bits ;)

struct{
  int b0 : 1;
  int b1 : 1;
  int b2 : 1;
};

Avec l’utilisation de l’opérateur ternaire, on obtient quelque chose comme ça :

struct{
  int data_test : sizeof(data) > MAX_SIZE ? -1 : 1;
  int data2_test : sizeof(data2) > MAX_SIZE ? -1 : 1;
  int data3_test : sizeof(data3) > MAX_SIZE ? -1 : 1;
};

Dans ce cas, l’utilisation d’une structure anonyme avec des champs de bits peut servir à regrouper différents tests sans nécessairement allouer de mémoire comme avec l’exemple précédent.


Pour résumer :

Comme le sizeof n’est pas toujours reconnu par le préprocesseur, préférez une déclaration de structure anonyme pour regrouper vos tests similaires de sizeof

Ça tient sur une ligne, c’est portable et contenu dans un bloc 🙂

À vos claviers 😉



 
 

© LH&TECH, tous droits réservés.

bottom of page