Voici le problème: Votre programme temporairement Utilise des données sensibles et veut l'effacer quand il n'est plus nécessaire . Utilisation de Utilisateur ybungalobill suggère Utilisation L'intention est que lors de la vue du mot clé code> volatile code> Le compilateur n'essaiera pas d'éliminer l'appel à sera < Code> Volatile Code> Le mot-clé empêche toujours le compilateur de cette mémoire modifiant la mémoire d'élimination du code? p> p> std :: Remplissage () Code> On lui aide toujours toujours - le compilateur peut décider que le bloc de mémoire n'est pas accessible ultérieurement, alors l'effacement est une perte de temps em> et éliminer l'effacement du code.
volatile code> mot-clé
: p> std :: Fill_N () code>. P>
4 Réponses :
du dernier brouillon C ++ 0x [INTRO.EXECUTION]: P>
8 le moins d'exigences sur un La mise en œuvre conforme est: p>
- L'accès à des objets volatils sont évalué strictement selon le Règles de la machine abstraite. P>
[...] p>
12 Accéder à un objet désigné par un Glvalue volatile (3.10), modifiant un objet, appelant une bibliothèque E / S fonction ou appeler une fonction qui Est-ce que l'une de ces opérations sont toutes effets secondaires, [...] p> blockQuote>
Donc, même le code que vous avez fourni ne doit pas être optimisé. P>
Au moins, les effets secondaires de l'écriture à des objets volatils ne doivent pas être supprimés sous la règle AS-si, ce qui signifie que le code fait ce qu'il devrait. Le compilateur est toujours libre d'effectuer d'autres optimisations dans Fill_N CODE>, telles que la boucle déroulante ou les optimisations de peephole d'assembleur.
Le contenu de la mémoire que vous souhaitez supprimer peut avoir déjà été rincé de votre cache interne de la CPU / CORE en RAM, où d'autres processeurs peuvent continuer à le voir. Après avoir écrasé, vous devez utiliser une instruction de mouton / barrière de mémoire / une opération atomique ou quelque chose pour déclencher une synchronisation avec d'autres cœurs. Dans la pratique, votre compilateur fera probablement cela avant d'appeler des fonctions externes (Google Dave Butenhof's Post sur l'utilitaire douteux de volatile dans la multi-threading), de sorte que si vous le filetez-le, il n'est donc pas un problème majeur. Sommairement: la volatilité n'est pas nécessaire. P>
Le compilateur est libre d'optimiser votre code car La norme nécessite uniquement qu'un compilateur adhère strictement à la sémantique des objets volatils. Voici ce que C ++ 03 dit P>
Le moins d'exigences sur une implémentation conforme sont: p>
et p>
Le comportement observable de la machine abstraite est sa séquence de lecture et écrit aux données volatiles et
Appels vers les fonctions d'E / S de la bibliothèque P>
blockQuote>
Dans votre exemple, ce que vous avez est lu et écrit à l'aide d'objets volatils à des objets non volatils. C ++ 0x a supprimé le deuxième texte que j'ai cité ci-dessus, car il est redondant. C ++ 0x dit simplement P>
Le moins d'exigences sur une implémentation conforme sont: p>
Celles-ci collectivement sont appelées comportement observables em> du programme. p>
blockQuote>
On peut affirmer que "les données volatiles" pourrait peut-être signifier "les données accessibles par des lvalues volatiles", qui seraient toujours assez étirées, le libellé C ++ 0x a supprimé tous les doutes sur votre code et permet clairement des implémentations de l'optimiser loin. p>
Mais comme les gens m'ont souligné, cela n'a probablement pas d'importance dans la pratique. Un compilateur qui optimise une telle chose va probablement aller contre l'intention des programmeurs (pourquoi quelqu'un aurait-il un pointeur à volatilité autrement) et contiendrait probablement un bug. Néanmoins, j'ai connu des vendeurs compilateurs qui ont cité ces paragraphes lorsqu'ils étaient confrontés à des bugReports sur leurs optimisations trop agressives. En fin de compte, tampon code> n'est pas un objet volatil em>. p>
volatile code> est spécifique à la plate-forme inhérente et vous êtes censé vérifier le résultat de toute façon. p>
_Pourquoi ces règles ont tendance à jouer avec des mots?
Une implémentation conforme peut, à sa loisirs, différer les performances réelles de toutes les lectures volatiles et écrites jusqu'à ce que le résultat d'une lecture volatile affecterait l'exécution d'une opération d'écriture volatile ou d'E / S.
Par exemple, donné quelque chose comme: p> un compilateur conforme pourrait, à son option, vérifier si échelle code> est un multiple de 128 et - si oui - clair Toutes les valeurs même indexées de
res code> avant de faire des lectures de
vol1 code> ou écrit sur
vol2 code>. Même si le compilateur aurait besoin de faire chaque lecture de
vol1 code> avant de pouvoir effectuer l'écriture suivante sur
vol2 code>, un compilateur peut être capable de différer les deux opérations jusqu'à ce qu'il soit exécuté une quantité de code essentiellement illimitée. p> p>
Hmmm, je pense que ce n'est pas la situation exacte. Ici, le compilateur sait que la mémoire est allouée sur la pile, il n'y a pas. (Donc, cela peut indiquer un registre mappé de mémoire)
J'étais sur le point de poster une question similaire concernant cette réponse. Funny Comment une préoccupation peut collecter beaucoup d'autres questions intéressantes;) Voici mon +1.
Essayez de déclarer la mémoire tampon sous forme de mémoire tampon [Taille] volatile [Taille]; code> plutôt que de la jeter dans l'appel à
std :: Fill_n code>.