Représentation de piège, caractère non signé et IA64 NaT

Source: Les déchets non initialisés sur ia64 peuvent être mortels

Sur le ia64, chaque registre de 64 bits est en réalité de 65 bits. Le bit supplémentaire s’appelle “NaT”, ce qui signifie “pas une chose”. Le bit est activé lorsque le registre ne contient pas de valeur valide. Considérez-le comme la version entière du NaN à virgule flottante.

Le bit NaT est défini le plus souvent à partir d’une exécution spéculative. Il existe une forme spéciale d’instruction de chargement sur l’ia64 qui tente de charger la valeur à partir de la mémoire, mais si le chargement échoue (parce que la mémoire est paginée ou que l’adresse est invalide), alors, au lieu de déclencher une erreur de page, est-ce que le bit NaT est activé et l’exécution se poursuit.

Toutes les opérations mathématiques sur NaT produisent à nouveau NaT.

L’article source explique ensuite comment un registre peut avoir une représentation NaT lors d’un chargement spéculatif et fait la remarque suivante:

Car vous voyez, si vous avez un registre dont la valeur est NaT et que vous y respirez mal (par exemple, essayez de sauvegarder sa valeur en mémoire), le processeur lève une exception STATUS_REG_NAT_CONSUMPTION.

d’autres réponses de débordement de stack à des représentations Trap qui,
“Tout type (à l’exception des caractères non signés) peut avoir des représentations de déroutement”.

Ce lien dit que

Les seules garanties données par la norme sur l’access aux données non initialisées sont que le type char non signé ne comporte aucune représentation d’interruption et que le remplissage ne contient aucune représentation d’interruption.

Si un tel registre (un registre avec un bit NaT défini) est alloué pour stocker un caractère non signé non signé (similaire au fragment de code du rapport de défaut ci-dessous), comment est-il géré conformément à la norme ISO C11?

Le rapport de défaut ci-dessous indique-t-il le même problème et est-il corrigé dans ISO C11?

Si non, comment ce cas particulier est-il traité?

Si la valeur lvalue désigne un object de durée de stockage automatique qui aurait pu être déclaré avec la classe de stockage register (son adresse n’a jamais été prise) et que cet object est non initialisé (non déclaré avec un initialiseur et qu’aucune affectation n’a été effectuée utiliser), le comportement est indéfini

L’ajout ci-dessus à la fin du rapport de défaut dans la section “changer pour C1X” gère-t-il ce cas?

defect_report

La fonction suivante a un comportement non défini sous C90, mais semble être ssortingctement conforme à C99.

int foo(void) { unsigned char uc; return uc + 1 >= 0; } 

Tout d’abord, si vous ne l’avez pas vu vous-même, vous pouvez récupérer ici la version finale de la norme C11 ( voir aussi ).

Le texte du DR a bien été ajouté à la section 6.3.2.1 p2, ce qui rend le code extrait indéfini conformément à C11.

Les sections de la norme sur les représentations d’interruption continuent d’exclure la possibilité que unsigned char puisse avoir une représentation d’interception – mais cela n’a pas d’importance. Il convient de noter ici que, comme le note la note de spring 2008 du DR, d’un sharepoint vue standard, il n’est pas nécessaire que les représentations de piège soient impliquées elles-mêmes (c’est simplement le mécanisme probable par lequel l’UB causera une problème pour vous sur le métal). Le problème concerne vraiment les valeurs automatiques non initialisées; le paragraphe modifié résout ce problème en précisant que unsigned char ne doit pas être considéré comme exempt d’un type général d’UB simplement en raison de l’ une de ses propriétés spécifiques au type (pas en ajoutant davantage de complexité à cette propriété).

Vous pouvez imaginer que, tout comme les bits NaT sont un détail d’implémentation d’entiers sur IA64, l’absence de représentation de déroutement est un “détail d’implémentation” d’un type particulier de la famille générale des types C. Le type réel de la variable est secondaire à la règle plus générale selon laquelle vous ne devez pas avoir le sentiment d’accéder à une variable non initialisée. l’addition clarifie cette priorité.