Priorite

Vous avez peut être vu cette construction


int main (int argc, char *argv[]) {

}

Selon la manière dont la priorité s’applique *argv[] peut être lu de deux manières. Admettons que nous compilions vers une architecture 64 bits avec des pointeurs codés sur 8 octets : dans le cas où le pointeur s’applique avant le tableau char (*argv)[] argv serait un pointeur (de 8 octets) pointant sur un tableau de caractères (dont chaque élément est un char et dont l’arithmétique serait de base 1). Si le tableau a une plus grande priorité que le pointeur char *(argv[]), argv serait un tableau (donc un pointeur de 8 octets) dont chaque élément est un pointeur, et l’arithmétique sur un tel tableau serait de base 8.

Concrètement argv[1] lirait à un octet après l’adresse de argv dans le premier cas et à 8 octets à l’adresse de argv dans le seond cas. Il est donc important de connaitre la priorité des opérateurs en C, la connaitre par coeur pour ne pas avoir à la revérifier en ligne est une compétrence qu’on peut considérer comme acquise chez un développeur expérimenté. Dans du code industriel on peut aussi rendre obligatoire l’utilisation de paranthèses lorsque deux opérateurs ou plus cohabitent dans la même expression : c’est à dire que a = a + a * 2 ne serait pas autorisé, il faudrait écrire a = (a + (a * 2)) même si cela peut paraitre évident pour un développeur C expérimenté.

Voilà les règles de priorité à connaitre :

En conséquence vous pouvez reconnaitre d’un coup d’oeil que char * const (*(* const bar)[5])(int ) déclare bar comme un pointeur constant vers un tableau de 5 pointeurs sur des fonctions acceptants un int et retournants un pointeur constant vers char. Pour vous aider, vous pouvez utiliser le site https://cdecl.org 🌍⤴