Pourquoi différents compilateurs C peuvent-ils donner différents résultats pour un programme C?

J’ai un doute sur la raison pour laquelle il arrive que différents compilateurs donnent différentes sorties à un même programme C. S’il existe un C standard, pourquoi ces fameux compilateurs ne l’utilisent pas complètement. la différence de sortie est provoquée par les compilateurs 16 bits, 32 bits, alors quels sont tous ces problèmes qui font la différence.

Le standard de langage laisse plusieurs degrés de liberté aux implémentations.

Premièrement, même si le programme est correctement implémenté, son comportement peut dépendre des fonctionnalités de langage définies par celle-ci. Par exemple, différentes implémentations peuvent avoir différentes plages pour les types entiers de base.

Deuxièmement, le programme pourrait simplement être interrompu. Un programme interrompu dans ce contexte est un programme qui repose sur un comportement indéfini ou non spécifié par le langage. Ce programme semblera “fonctionner” d’une certaine manière, mais son comportement réel dépendra de facteurs imprévisibles et, par conséquent, sera incohérent.

La pratique montre que dans de nombreux cas (si ce n’est la plupart des cas), lorsque les gens se plaignent d’un comportement incohérent des programmes C, ils ne réalisent pas qu’ils ont un programme défaillant.

Avez-vous un exemple?

Le langage est normalisé, mais de nombreux aspects sont définis par la mise en œuvre, voire non définis.

Par exemple, ceci:

printf("sizeof (int) = %u\n", (unsigned)sizeof (int)); 

imprimera différents numéros sur différents systèmes, en fonction de la taille de votre int .

Il y a beaucoup de choses dans C qui sont définies par l’implémentation. Cela signifie que les personnes qui créent les compilateurs peuvent choisir comment elles veulent gérer ces situations. En général, pour la portabilité, il est préférable dans la plupart des cas de ne pas compter sur un comportement indéfini, même lorsque la plupart ou la totalité des compilateurs le traitent de la même manière. Si vous fournissez du code que différents compilateurs traitent différemment, nous pourrons peut-être vous dire pourquoi ils le font et comment le corriger.

Un exemple de comportement non défini consiste à référencer une variable non initialisée comme celle-ci:

 int *a; printf("%d", *a); 

Dans la plupart des implémentations, vous verrez un entier indésirable qui ne veut rien dire (avec un avertissement). Il s’agit de la valeur stockée dans l’emplacement de mémoire désigné par a ; toutefois, techniquement, l’implémentation aurait pu spécifier que le référencement d’une variable non initialisée donnera toujours 0 (ou quelque chose comme ça). La raison pour laquelle ce n’est pas le cas, c’est parce que c’est beaucoup plus difficile à mettre en œuvre. Néanmoins, vous ne devez toujours pas compter sur ce qui est dans la mémoire indiquée par a . Ce peut être ou ne pas être ce que vous obtenez.

La plupart du temps, c’est lorsqu’un programmeur utilise un comportement indéfini et que le compilateur doit essayer de deviner ce que vous voulez dire.

Exemple d’un autre problème potentiel: C ++ 0x vient d’être approuvé, mais le brouillon final n’est pas accessible au public. Dès qu’il sera disponible, certains compilateurs pourront append du support avant les autres.

Partie de solution: De nombreux compilateurs ont un moyen de comstackr selon certaines spécifications. Par exemple, avec GCC, vous pouvez comstackr avec “gcc nom_programme.c -ansi” pour vous assurer que votre code est conforme à la norme ANSI. Cela consortingbuera à assurer la cohérence.