Bases de la programmation en C

int get(int *p) {
    int v = *p;
    if (p == NULL)
        return -1;
    return v;
}

Lorsque la fonction ci-dessus est compilée avec gcc en activant l'optimisation, le test if (p == NULL) peut être supprimé. Quelle en est la raison ?

  1. A*p est lu d'abord, et si p valait NULL, ce serait déjà un comportement indéfini : le compilateur peut donc supposer que p n'est pas NULL
  2. BLa norme prévoit qu'une comparaison avec NULL est toujours fausse
  3. CAvec l'optimisation, les instructions if qui vérifient les arguments d'une fonction sont considérées comme relevant de l'appelant, et peuvent toutes être supprimées
Afficher la réponse et l'explication

Réponse : A. *p est lu d'abord, et si p valait NULL, ce serait déjà un comportement indéfini : le compilateur peut donc supposer que p n'est pas NULL

Si p vaut NULL, int v = *p;, exécuté en premier, déréférence un pointeur NULL et constitue dès ce moment un comportement indéfini. Le compilateur pouvant supposer qu'aucun comportement indéfini ne se produit, il conclut que p n'est pas NULL puisque *p a été lu, et supprime le test p == NULL ainsi que le return -1. Avec gcc 13 pour x86-64 et l'option -O2, la fonction devient un code qui se contente de lire *p et de le renvoyer, alors qu'à -O0 le test est conservé. Pour que le test soit vraiment efficace, on vérifie p avant de lire *p.

S'entraîner sur ce thème Retour au thème

Autres questions sur Bases de la programmation en C

  1. Que fixe la norme du langage C au sujet de la taille du type int ?
  2. Dans les programmes embarqués, une variable qui reçoit la valeur d'un registre de périphérique de 32 bits est souvent déclarée avec le type uint32_t de stdint.h plutôt qu'avec unsigned int. Quelle en est la raison principale ?
  3. Quelle est la sortie obtenue en exécutant le code ci-dessus, qui contient une division entre entiers ?
  4. Quelle est la sortie obtenue en exécutant le code ci-dessus, qui utilise ++ en préfixe et en suffixe ?
  5. Quelle est la sortie obtenue en exécutant le code ci-dessus, où = est écrit dans la condition d'une instruction if ?