ProgrammationDéveloppeur Backend Intermédiaire

Expliquez le fonctionnement de l'opérateur virgule (comma operator) dans le langage C. Quand son utilisation est-elle justifiée et quels effets secondaires inattendus peuvent survenir en raison d'une compréhension ambiguë de l'ordre d'évaluation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

L'opérateur virgule (,) en C permet de combiner plusieurs expressions, dont le résultat est la valeur de la dernière expression.

Exemple:

int a = 1, b = 2, c; c = (a += 2, b += 3, a + b); // d'abord on incrémente a, puis b, puis on additionne a + b

Utilisation:

  • Souvent utilisé dans l'en-tête d'une boucle for, où plusieurs actions doivent être exécutées.
  • Parfois utilisé pour combiner des expressions dans des macros et des expressions complexes.

Subtilités:

  • L'opérateur virgule a la priorité la plus basse parmi les opérateurs binaires.
  • Dans les listes d'initialisation, les listes d'arguments et les énumérations, la virgule n'est pas un opérateur ! Ici, c'est un séparateur.
  • Les expressions dans l'opérateur virgule sont évaluées de gauche à droite.

Exemple de boucle:

for (i = 0, j = 10; i < j; ++i, --j) { /* ... */ }

Question piégée.

Quelle est la différence entre la virgule en tant qu'opérateur et en tant que séparateur dans une liste d'arguments de fonction ?

Erreur courante: On pense que la virgule est un opérateur à tout moment et qu'elle combine toujours des expressions.

Réponse correcte: La virgule est un opérateur seulement en dehors des listes d'initialisation, d'arguments et des éléments de tableau. Par exemple:

int x = (1, 2); // x == 2, ici c'est un opérateur void foo(int a, int b) { ... } // ici c'est un séparateur

La virgule en tant qu'opérateur ne fonctionne que dans les parenthèses, dans les autres cas, elle est simplement un séparateur.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet.


Histoire

Une macro, où à l'intérieur de do { ... } while (0) l'opérateur virgule était utilisé pour combiner des instructions sans parenthèses, a entraîné quelque chose comme if (a) MACRO(); else ... provoquant une erreur de syntaxe en raison d'une mauvaise syntaxe de la macro.


Histoire

La confusion entre la priorité de l'opérateur virgule et la priorité de l'affectation conduisait à ce que l'expression a = b, c = d; fonctionnait comme (a = b), (c = d), tandis que le programmeur pensait que les deux affectations se faisaient simultanément comme partie d'une seule expression.


Histoire

Dans une fonction, la virgule était utilisée pour appeler des fonctions de manière séquentielle, mais il était ignoré que seule la dernière valeur était retournée. On supposait que l'expression résultante combinait les effets de tous les appels, alors qu'en réalité, seuls les effets secondaires des premiers appels comptaient, et leurs valeurs retournées étaient perdues.