547 votes

Pourquoi le volatile est-il nécessaire en c ?

Pourquoi est-ce que volatile nécessaire en C ? A quoi sert-il ? Que fera-t-il ?

20voto

Alexandre C. Points 31758

Une utilisation marginale de volatile est la suivante. Disons que vous voulez calculer la dérivée numérique d'une fonction f :

double der_f(double x)
{
    static const double h = 1e-3;
    return (f(x + h) - f(x)) / h;
}

Le problème est que x+h-x n'est généralement pas égal à h en raison d'erreurs d'arrondi. Pensez-y : lorsque vous soustrayez des nombres très proches, vous perdez beaucoup de chiffres significatifs qui peuvent ruiner le calcul de la dérivée (pensez à 1.00001 - 1). Une solution de contournement pourrait être la suivante

double der_f2(double x)
{
    static const double h = 1e-3;
    double hh = x + h - x;
    return (f(x + hh) - f(x)) / hh;
}

mais en fonction de votre plate-forme et des commutateurs de compilateur, la deuxième ligne de cette fonction peut être effacée par un compilateur à optimisation agressive. Vous écrivez donc à la place

    volatile double hh = x + h;
    hh -= x;

pour forcer le compilateur à lire l'emplacement mémoire contenant hh, en renonçant à une éventuelle opportunité d'optimisation.

0 votes

Quelle est la différence entre utiliser h o hh dans la formule dérivée ? Lorsque hh est calculé la dernière formule l'utilise comme la première, sans différence. Peut-être que cela devrait être (f(x+h) - f(x))/hh ?

2 votes

La différence entre h y hh c'est que hh est tronquée à une puissance négative de deux par l'opération x + h - x . Dans ce cas, x + hh y x diffèrent exactement par hh . Vous pouvez aussi prendre votre formule, elle donnera le même résultat, puisque x + h y x + hh sont égales (c'est le dénominateur qui est important ici).

3 votes

Une façon plus lisible d'écrire ceci ne serait-elle pas x1=x+h; d = (f(x1)-f(x))/(x1-x) ? sans utiliser le volatile.

11voto

Neo Cambell Points 21

Il y a deux utilisations. Ils sont surtout utilisés plus souvent dans le développement embarqué.

  1. Le compilateur n'optimisera pas les fonctions qui utilisent des variables définies avec le mot clé volatile.

  2. Volatile est utilisé pour accéder à des emplacements mémoire exacts en RAM, ROM, etc... On l'utilise plus souvent pour contrôler les dispositifs à mémoire vive, accéder aux registres du CPU et localiser des emplacements mémoire spécifiques.

Voir les exemples avec la liste des assemblages. Re : Utilisation du mot clé "volatile" en C dans le développement embarqué

2 votes

"Le compilateur n'optimisera pas les fonctions qui utilisent des variables définies avec le mot clé volatile" - c'est tout simplement faux.

10voto

Alexey Frunze Points 37651

Je vais mentionner un autre scénario où les volatiles sont importants.

Supposons que vous mappez la mémoire d'un fichier pour accélérer les entrées/sorties et que ce fichier peut changer en coulisses (par exemple, le fichier n'est pas sur votre disque dur local, mais est servi sur le réseau par un autre ordinateur).

Si vous accédez aux données du fichier mappé en mémoire par le biais de pointeurs vers des objets non volatils (au niveau du code source), le code généré par le compilateur peut aller chercher les mêmes données plusieurs fois sans que vous en soyez conscient.

Si ces données changent, votre programme peut utiliser deux ou plusieurs versions différentes des données et se retrouver dans un état d'incohérence. Cela peut entraîner non seulement un comportement logiquement incorrect du programme, mais aussi des failles de sécurité exploitables s'il traite des fichiers non fiables ou des fichiers provenant d'emplacements non fiables.

Si vous vous souciez de la sécurité, et vous devriez le faire, c'est un scénario important à prendre en compte.

9voto

Diomidis Spinellis Points 8417

Volatile est également utile, lorsque vous voulez forcer le compilateur à ne pas optimiser une séquence de code spécifique (par exemple pour écrire un micro-benchmark).

6voto

Volatile signifie que le stockage est susceptible de changer à tout moment et d'être modifié par quelque chose qui échappe au contrôle du programme utilisateur. Cela signifie que si vous faites référence à la variable, le programme doit toujours vérifier l'adresse physique (c'est-à-dire un fifo d'entrée mappé), et ne pas l'utiliser de manière cachée.

Voir aussi l'article à http://clinuxpro.com/volatile-in-c

2 votes

Aucun compilateur ne prend le terme volatile pour signifier soit "adresse physique en RAM", soit "contourner le cache".

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