74 votes

Un comportement ^ a ou aa non défini si un n'est pas initialisé?

Considérez ce programme:

 #include <stdio.h>

int main(void)
{
    unsigned int a;
    printf("%u %u\n", a^a, a-a);
    return 0;
}
 

Son comportement est-il défini?

A première vue, a est une variable non initialisée. Donc, cela pointe vers un comportement indéfini. Mais a^a et a-a sont égaux à 0 pour toutes les valeurs de a , du moins je pense que c'est le cas. Est-il possible qu'il y ait un moyen de faire valoir que le comportement est bien défini?

72voto

Matt McNabb Points 14273

En C11:

  • Il est explicitement non défini selon 6.3.2.1/2 si a n'a jamais son adresse (cité ci-dessous)
  • Il pourrait être un piège de la représentation (ce qui provoque UB lors de l'accès). 6.2.6.1/5:

Certaines représentations objet n'a pas besoin de représenter une valeur du type d'objet.

Unsigned ints peut avoir piège des représentations (par exemple, si elle a 15 précision bits et 1 bit de parité, d'accéder a pourrait provoquer une parité faute).

6.2.4/6 dit que la valeur initiale est de durée indéterminée et la définition de ce sous 3.19.2 est soit une valeur indéterminée ou d'un piège de la représentation.

Plus loin: C11 6.3.2.1/2, comme l'a souligné Pascal Cuoq:

Si la lvalue désigne un objet de stockage automatique de la durée qui aurait pu être déclarée au registre de classe de stockage (n'a jamais eu son adresse), et que cet objet est non initialisée (pas déclarée avec un initialiseur et aucune affectation n'a été effectuée avant l'utilisation), le comportement est indéfini.

Ce n'est pas l'exception pour les types de caractères, de sorte que cette clause apparaît à se substituer à la discussion qui précède; accéder x est immédiatement undefined même si pas de piège représentations existent. Cette clause a été ajoutée à C11 à l'appui de Itanium Cpu qui n'ont en réalité un piège état des registres.


Les systèmes sans piège des représentations: Mais que faire si nous jeter dans &x; de sorte que le 6.3.2.1/2 objection ne s'applique plus, et nous sommes sur un système qui est connu pour avoir aucun piège des représentations? La valeur est une valeur indéterminée. La définition de valeur quelconque dans 3.19.3 est un peu vague, cependant, il est précisé par le DR 451, qui conclut:

  • Une valeur non initialisée dans les conditions décrites ci-dessus peuvent apparaître pour modifier sa valeur.
  • Toute opération effectuée sur une période indéterminée valeurs sont d'une durée indéterminée de la valeur.
  • Les fonctions de la bibliothèque présentent un comportement indéfini lorsqu'il est utilisé sur une période indéterminée valeurs.
  • Ces réponses sont appropriées pour tous les types qui n'ont pas de piège représentations.

En vertu de la présente résolution, int a; &a; int b = a - a; résultats en b ayant une valeur indéterminée encore.

Notez que si la durée indéterminée de la valeur n'est pas passé à une fonction de la bibliothèque, nous sommes toujours dans le domaine de la non spécifiée comportement (pas un comportement indéterminé). Les résultats peuvent être bizarre, par exemple, if ( j != j ) foo(); pourrait appeler foo, mais les démons doivent rester caché dans la cavité nasale.

32voto

AndreyT Points 139512

Oui, c'est un comportement indéfini.

Tout d'abord, une variable non initialisée peut avoir "brisé" (aka "piège") de la représentation. Même une seule tentative d'accès à cette représentation déclenche un comportement indéfini. En outre, même les objets de la non-piégeage types (comme unsigned char) peut toujours acquérir spécial de la plate-forme dépendante des états (comme NaT - Pas-Une-Chose - sur Itanium) qui peut apparaître comme une manifestation de leur "une valeur indéterminée".

D'autre part, une variable non initialisée est pas la garantie d'avoir un stable de la valeur. Deux séquentielle a accès à la même variable non initialisée pouvez lire complètement différentes valeurs, c'est pourquoi, même si les deux accès en a - a sont des "succès" (pas de piégeage), il n'est toujours pas garanti qu' a - a évaluera à zéro.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X