Maison > développement back-end > C++ > le corps du texte

Pourquoi l'attribution d'une valeur à une variable complexe provoque-t-elle une boucle infinie dans un programme C, même si cela semble être une action apparemment anodine ?

Linda Hamilton
Libérer: 2024-10-30 04:29:02
original
116 Les gens l'ont consulté

Why does assigning a value to a complex variable cause an infinite loop in a C   program, even though it appears to be a seemingly innocuous action?

Énigme de compilation C avec comportement de boucle imprévisible

Le code suivant présente un problème de compilation intrigant :

<code class="c++">#include <iostream>
#include <complex>
using namespace std;

int main() {
    complex<int> delta;
    complex<int> mc[4] = {0};

    for(int di = 0; di < 4; di++, delta = mc[di]) {
        cout << di << endl;
    }

    return 0;
}</code>
Copier après la connexion

Contraire à la sortie attendue de "0, 1, 2, 3", le code produit une répétition sans fin de "0, 1, 2, 3, 4, 5, ...". Après enquête, il semble que la comparaison di < 4 ne fonctionne pas correctement, ce qui entraîne une boucle infinie.

La désactivation de l'affectation apparemment anodine delta = mc[di] résout comme par magie le problème, générant le résultat souhaité. Quel est le problème que pose cette simple action ?

Plonger dans un comportement indéfini

La clé pour percer ce mystère réside dans la compréhension d'un comportement indéfini. L'affectation delta = mc[di] déclenche un accès à un tableau hors limites lors de la dernière itération de la boucle. Bien que de nombreux compilateurs puissent supposer qu'aucun comportement indéfini n'est basé sur des stratégies d'optimisation, cette hypothèse est intrinsèquement erronée.

GCC, avec les optimisations activées, peut optimiser de manière agressive la boucle en supposant l'absence de comportement indéfini. Cette optimisation conduit à une inférence erronée selon laquelle di < 4 est toujours vrai, car un accès hors limites au tableau constituerait un comportement indéfini.

En conséquence, la boucle devient infinie, car la condition di < 4 est toujours respecté. Pour éviter cette optimisation erronée, l'indicateur -fno-aggressive-loop-optimizations peut être ajouté à GCC.

Dévoilement du fonctionnement interne du compilateur

Un examen plus approfondi du le code optimisé révèle que le di < 4 check est supprimé et remplacé par une instruction jmp inconditionnelle. Ce comportement s'aligne sur l'hypothèse d'aucun comportement indéfini, ce qui entraîne une boucle infinie.

Contrairement à ce comportement, Clang avec -fsanitize=undefined attraperait ce cas. Cependant, GCC avec le même indicateur ne parvient pas à émettre un avertissement dans ce cas spécifique.

Les périls d'un comportement non défini

Comportement non défini, tel que défini par la norme C, permet des résultats imprévisibles, y compris en ignorant complètement la situation. Un comportement non défini doit être évité à tout prix, car il peut entraîner à la fois des incohérences du compilateur et un comportement d'exécution inattendu.

Pour éviter de tels pièges, les programmeurs doivent s'efforcer d'obtenir un code bien défini qui adhère à la sémantique prévue. Les compilateurs doivent également mettre en œuvre des défenses appropriées pour alerter les développeurs d'un comportement potentiel non défini.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!