Je vais juste ajouter une référence détaillée pour le cas de la règle et de la volatilité de mot-clé. (Au bas de ces pages, de suivre les "voir aussi" et "Références" à remonter à l'origine des specs, mais je trouve cppreference.com beaucoup plus facile à lire/comprendre.)
En particulier, je veux que vous lisiez cet article
volatile de l'objet - un objet dont le type est volatile-qualifiés, ou un sous-objet d'un objet volatile, ou une mutable sous-objet d'un const volatile de l'objet. Tous les accès (lecture ou d'écriture, membre de l'appel de fonction, etc.) fait au travers d'un glvalue expression de la volatilité des qualifiés de type est traité comme un visible des effets secondaires pour l'application de l'optimisation (qui est, dans un seul thread d'exécution, accès volatiles ne peut pas être optimisé ou réorganisée avec un autre visible effet secondaire qui est séquencé en-avant ou séquencés-après de la volatilité de l'accès. Cela rend volatile des objets appropriés pour la communication avec un gestionnaire de signal, mais pas avec un autre thread d'exécution, voir std::memory_order). Toute tentative de se référer à un volatile de l'objet par l'intermédiaire d'un non-volatile glvalue (par exemple par le biais d'une référence ou un pointeur non volatile de type) entraîne un comportement indéfini.
Si le mot clé volatile spécifiquement est sur la désactivation de l'optimisation du compilateur sur glvalues. La seule chose ici, le mot clé volatile peut affecter est peut-être return x
, le compilateur peut faire ce qu'il veut avec le reste de la fonction.
Combien le compilateur peut optimiser le rendement dépend de la façon dont beaucoup le compilateur est permis d'optimiser l'accès à x dans ce cas (car il n'est pas réorganisation de quoi que ce soit, et à proprement parler, n'est-ce pas la suppression de l'expression de renvoi. Il y a l'accès, mais il est la lecture et l'écriture de la pile, ce qui est devrait être en mesure de rationaliser.) Donc, comme je l'ai lu, c'est une zone grise dans la façon dont beaucoup le compilateur est autorisé à optimiser, et peut facilement être soutenu dans les deux sens.
Remarque: Dans ces cas, supposons toujours que le compilateur va faire le contraire de ce que vous voulez/besoin. Vous pouvez soit désactiver l'optimisation (au moins pour ce module), ou à essayer de trouver un comportement défini pour ce que vous voulez. (C'est aussi pourquoi les tests unitaires est tellement important) Si vous croyez que c'est un défaut, vous devez apporter avec les développeurs de C++.
Tout cela est encore très difficile à lire, donc, essayer d'inclure ce que je trouve pertinents, de sorte que vous pouvez lire vous-même.
glvalue Un glvalue expression est soit lvalue ou xvalue.
Propriétés:
Un glvalue peut être implicitement converti en prvalue avec
lvalue-à-rvalue, tableau de pointeur, ou de la fonction de pointeur implicite
la conversion. Un glvalue peut être polymorphe: le type dynamique de l'
objet il identifie n'est pas nécessairement le type statique de l'
de l'expression. Un glvalue peuvent être incomplètes type, lorsque cela est autorisé par la
de l'expression.
xvalue, Les expressions suivantes sont xvalue expressions:
un appel de fonction ou un opérateur surchargé d'expression, dont le retour
type référence rvalue pour objet, comme std::move(x); a[n], la
intégré dans l'indice de l'expression, où l'un des opérandes est un tableau rvalue ;
un.m, le membre de l'objet de l'expression, où a est une rvalue et m est un
non-membre de données statiques de non-type de référence; un.*mp, le pointeur de
membre de l'objet de l'expression, où a est une rvalue et mp est un pointeur
pour le membre de données; un ? b : c, le ternaire expression conditionnelle pour certains
b et c (voir la définition de détail); une expression cast à rvalue
de référence pour le type d'objet, comme static_cast(x); toute
expression qui désigne un objet temporaire, après temporaire
la matérialisation. (depuis C++17) Propriétés:
Même que rvalue (ci-dessous). Même que glvalue (ci-dessous). En particulier, comme
tous les rvalues, xvalues se lier à des références rvalue, et comme tous les glvalues,
xvalues peut être polymorphe, et non de la classe xvalues peut être de cv qualifiés.
lvalue, Les expressions suivantes sont lvalue expressions:
le nom d'une variable, une fonction, ou un membre de données, indépendamment de
type, comme std::cin ou std::endl. Même si le type de la variable est
référence rvalue, l'expression composée de son nom est une lvalue
expression; un appel de fonction ou un opérateur surchargé d'expression,
dont le type de retour est lvalue de référence, tels que les std::getline(std::cin,
str), std::cout << 1, str1 = str2, ou ++il; a = b, a += b, a %= b, et
tous les autres intégrée d'attribution et d'assignation composé expressions;
++un et-un, le haut-pré-incrémentation et de pré-décrémentation expressions;
*p, le haut-indirection expression; a[n] et p[n], le haut-indice des expressions, sauf si a est une matrice de rvalue (depuis
C++11); une.m, le membre de l'objet de l'expression, à l'exception de, où m est un
membre de l'agent recenseur ou d'une fonction membre statique, ou où a est un
rvalue et m est un non-membre de données statiques de non-type de référence; p->m,
le membre intégré de pointeur expression, à l'exception de, où m est un membre
agent recenseur ou d'une fonction membre statique; un.*mp, le pointeur de
membre de l'objet de l'expression, où a est une lvalue et mp est un pointeur
pour le membre de données; p->*mp, le pointeur de membre de pointeur
l'expression, où mp est un pointeur vers les données de membre; a, b, intégré dans
virgule expression, où b est une lvalue; un ? b : c, le ternaire
expression conditionnelle pour certains, b et c (par exemple, lorsque les deux sont lvalues
du même type, mais voir la définition de détail); un littéral de chaîne,
comme "Hello, world!"; un casting expression de lvalue type de référence,
comme static_cast(x); un appel de fonction ou une surcharge
opérateur d'expression, dont le type de retour est rvalue référence à
fonction; une expression cast de référence rvalue au type de fonction, par exemple
comme static_cast(x). (depuis C++11) Propriétés:
Même que glvalue (ci-dessous). L'adresse d'une lvalue peuvent être prises: &++i1
et &std::endl sont des expressions valides. Modifiable lvalue peut être utilisé
que la gauche opérande de cession et composé
opérateurs d'affectation. Une lvalue peut être utilisé pour initialiser une lvalue
de référence; on associe un nouveau nom à l'objet identifié par
l'expression.
comme-si la règle
Le compilateur C++ est autorisé à effectuer les modifications apportées au programme aussi longtemps que la suite reste vrai:
1) À chaque point de séquence, les valeurs de tous les volatiles objets sont stables (évaluations précédentes sont complètes, de nouvelles évaluations de ne pas commencé)
(jusqu'à ce que C++11)
1) Accès (en lecture et en écriture) à la volatilité des objets se produisent strictement en fonction de la sémantique des expressions dans lesquelles ils se produisent. En particulier, ils ne sont pas réorganisées à l'égard des autres accès volatiles sur le même thread.
(depuis C++11)
2) À la fin du programme, les données écrites dans les fichiers est exactement comme si le programme a été exécuté comme à l'écrit.
3) texte d'Invite qui est envoyé aux dispositifs interactifs seront indiqués avant le programme attend d'entrée.
4) Si l'ISO C pragma #pragma STDC FENV_ACCESS est pris en charge et est réglé SUR on, les modifications apportées à la virgule flottante de l'environnement (les exceptions de virgule flottante et les modes d'arrondi) sont garantis d'être observé par l'arithmétique à virgule flottante opérateurs et des appels de fonction que si elle est exécutée comme l'écrit, sauf que
le résultat d'une expression à virgule flottante autre que la fonte et l'affectation peut avoir une autonomie et une précision de virgule flottante de type différent du type de l'expression (voir FLT_EVAL_METHOD)
nonobstant ce qui précède, les résultats intermédiaires de toute expression à virgule flottante peut être calculé comme si, à l'infini et de précision (sauf #pragma STDC FP_CONTRACT est DÉSACTIVÉ)
Si vous voulez lire les specs, je crois que ce sont ceux dont vous avez besoin pour lire
Références
C11 norme (ISO/IEC 9899:2011):
6.7.3 Type qualificatifs (p: 121-123)
Standard C99 (ISO/IEC 9899:1999):
6.7.3 Type qualificatifs (p: 108-110)
C89/C90 norme (ISO/IEC 9899:1990):
3.5.3 Type qualificatifs