Question

5.2.11 / 7 - [Remarque: Selon le type de l'objet, une opération d'écriture via le pointeur, le lvalue ou le pointeur vers un membre de données résultant d'une const_cast qui jette un const-qualilifier68) peut produire un comportement non défini (7.1.5.1). ] "

Les libellés de cette section (C ++ 03) me surprennent. Ce qui est surprenant, ce sont deux choses.

a) Tout d'abord, l'utilisation de «mai». Pourquoi est-ce «May»? D'autres endroits de la norme sont très définitifs sur le comportement non défini

b) Pourquoi est-ce que le casting de la construption d'un objet à l'origine non pas tout de suite «comportement non défini». Pourquoi une écriture est-elle requise pour que UB soit déclenché?

Était-ce utile?

La solution

a) Tout d'abord, l'utilisation de «mai». Pourquoi est-ce «May»? D'autres endroits de la norme sont très définitifs sur le comportement non défini

Ne regardez pas trop profondément dans l'utilisation du mot peut ici. Le fait est que la suppression de la construction dans ce cas provoque un comportement non défini.

La norme C ++ utilise «peut» ou «pourrait» souvent, comme dans:

1.3.12: comportement non défini peut On s'attend également à ce que cette norme internationale omet la description de toute définition explicite du comportement.

Accent le mien. Fondamentalement, la norme utilise le mot "peut" comme dans "est autorisé à".

b) Pourquoi est-ce que le casting de la construption d'un objet à l'origine non pas tout de suite «comportement non défini». Pourquoi une écriture est-elle requise pour que UB soit déclenché?

Une écriture déclenche UB car il est possible que les objets const peuvent être stockés dans une mémoire en lecture seule sur certaines plates-formes.

Autres conseils

Je comprends que ce ne sera UB que si l'objet en question est fondamentalement un objet const plutôt qu'un pointeur const ou une référence à un objet qui n'était pas à l'origine const.

L'idée étant que les données qui sont fondamentalement constantes pourraient être chargées dans une partie en lecture seule de la mémoire, et l'écrire à cela ne fonctionnera tout simplement pas. Cependant, il est garanti de fonctionner correctement si l'objet en question est fondamentalement mutable.

Ex:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.

Pour un commentaire ci-dessous, car le code semble terrible dans les commentaires:

Au §7.1. 5.1 / 4 de la norme, l'exemple donné est:

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object

C'est donc spécifiquement autorisé.

Pour votre première question, si quelque chose peut Produisez un comportement non défini, alors cela ne le rend pas moins défini.

Pour la deuxième partie, j'imagine que c'est pour des raisons d'interopérabilité. Par exemple, C n'a pas (ou n'a pas fait, avant C99) const Mot-clé, donc si vous voulez passer un objet const à une fonction C, la construption devrait être rejetée. Ainsi, la norme C ++ spécifie que cela est autorisé tant qu'aucune écriture n'est effectuée. Si la fonction C est en lecture seule, la construption peut être rejetée en toute sécurité.

Même en C ++, la correction constante incohérente ou incomplète est également assez courante. Nous rencontrons donc occasionnellement des situations où nous devons rejeter la constant afin de passer un objet const à une fonction qui ne modifie pas son argument, mais le prend par non-Const.

Je crois que c'est parce qu'un const L'objet peut être stocké en mémoire en lecture seule. Ainsi, l'écrire peut avoir de nombreux effets divers: crash du programme, défaut de segmentation ou aucun effet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top