variables en argument à la fonction
Avoir ce code:
typedef volatile int COUNT;
COUNT functionOne( COUNT *number );
int functionTwo( int *number );
Je ne peux pas me débarrasser de certaines mises en garde..
Je reçois cet avertissement 1 à functionOne prototype
[Avertissement] type de qualificatifs ignoré sur
type de retour de fonction
et je reçois cet avertissement 2, où que j'appelle functionTwo avec un nombre pointeur argument au lieu d'un int pointeur
[Avertissement] cast discards qualifiers
de pointeur de type de cible
évidemment variables/indicateurs ne peuvent pas être "jeté" à la volatilité des nations unies volatile.. mais tous les arguments doivent être indiqués comme étant volatile trop? alors, comment puis-je utiliser une fonction de la bibliothèque si elle est déjà défini pour les non-volatile variable?
MODIFIER: à l'Aide de gcc -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wextra -Wstrict-prototypes -Wmissing-prototypes …
MODIFIER: Après Jukka Suomela conseil ceci est un exemple de code d'avertissement de deux
typedef volatile int COUNT;
static int functionTwo(int *number) {
return *number + 1;
}
int main(void) {
COUNT count= 10;
count = functionTwo(&count);
return 0;
}
Je ne peux pas trouver une raison, mais si je ne fais pas de cette façon, je reçois un second avertissement me disant que je devrais spécifier volatils dans le prototype de la volatilité des variables
OriginalL'auteur Hernán Eche | 2010-07-21
Vous devez vous connecter pour publier un commentaire.
La
volatile
mot-clé a été conçue pour être appliquée à des objets qui représentent le stockage et non à des fonctions. Retour d'unvolatile int
à partir d'une fonction ne fait pas beaucoup de sens. La valeur de retour d'une fonction ne sera pas optimisé à l'écart (à l'exception possible des fonctions inline, mais c'est une autre affaire au total...), et aucun acteur externe sera de le modifier. Lorsqu'une fonction retourne, il transmet une copie de la valeur de retour à la fonction appelante. Une copie d'unvolatile
objet n'est pas lui-mêmevolatile
. Par conséquent, tenter de renvoyer unvolatile int
entraînera une copie, de coulée vers le bas pour un non-volatileint
, qui est ce qui est le déclenchement de vos messages compilateur. Retour d'unvolatile int*
pourrait être utile, mais pas unvolatile int
.Passage d'un objet par valeur à une fonction, une copie de l'objet, donc à l'aide d'un
volatile int
comme paramètre d'une fonction implique nécessairement une conversion qui ne tient pas compte d'un qualificatif. Le passage d'un volatile en fonction de l'adresse est parfaitement raisonnable, mais non par valeur.Selon les spec C, le comportement de
volatile
est complètement dépendant de l'implémentation, de sorte YMMV.Êtes-vous à l'aide de
volatile
dans ce sens pour essayer de vaincre une sorte d'optimisation du compilateur? Si oui, il y a sans doute une meilleure façon de le faire.Edit:
En prenant en compte les mises à jour à votre question, il semble que vous pouvez être en mesure à l'approche d'une autre façon. Si vous essayez de vaincre les optimisations du compilateur, pourquoi ne pas prendre l'approche directe et il suffit d'indiquer au compilateur de ne pas optimiser certaines choses? Vous pouvez utiliser
#pragma GCC optimiser
ou__attribute__((optimiser))
pour donner une optimisation des paramètres d'une fonction. Par exemple,__attribute__((optimize(0)))
devez désactiver toutes les optimisations pour une fonction donnée. De cette façon, vous pouvez garder vos types de données non-volatile et d'éviter le type de problèmes que vous rencontrez. Si la désactivation de toutes les optimisations est un peu trop, vous pouvez également activer l'optimisation individuelle ou désactivation des options de cet attribut/pragma.Edit:
J'ai été en mesure de compiler le code suivant sans erreurs ou avertissements:
Ce
hack"technique" a probablement un certain genre d'impair effets secondaires, afin de le tester à fond avant de l'utiliser en production. Ce n'est probablement pas différent que directement coulée de l'adresse d'un(int*)
, mais il ne donne pas lieu à des avertissements.OriginalL'auteur bta
Il est possible que je suis hors de la base ici, mais volatile n'est pas quelque chose normalement associés avec de la pile de la mémoire de la région. Donc je ne suis pas sûr si le prototype suivant fait vraiment beaucoup de sens.
Je ne suis pas sûr de savoir comment une entière retournée peuvent être volatils. Ce qui va causer de la valeur de EAX changer? La même chose s'applique à la valeur entière. Une fois que la valeur est poussé sur la pile de sorte qu'il peut être passé en paramètre ce qui va changer sa valeur?
Comme je le comprends, ce n'est pas une question de savoir si quelque chose peut changer une pile variable. La déclaration d'une pile de variable comme
volatile
force le compilateur à toujours lire / écrire la valeur de / vers l'emplacement de pile à la place de l'optimisation du code par la mise en cache de la pile de l'emplacement du contenu dans un registre.Je pense que si
functionOne
appellesetjmp
, modifiez la valeur denumber
, et appelle ensuite un peu de code qui appellelongjmp
à revenir ausetjmp
, les changements à la valeur denumber
serait garanti pour survivre à lalongjmp
si elle est déclaréevolatile
, mais ne serait pas ainsi de la garantie si elle n'était pas.OriginalL'auteur torak
Je ne comprends pas pourquoi vous voulez avoir la
volatile
qualifier sur un type de retour de fonction. La variable que vous affectez la valeur renvoyée de la fonction doit être tapé comme unvolatile
à la place.Essayez de faire ces changements:
Et lors de l'appel de
functionTwo()
, convertir explicitement l'argument:HTH,
Ashish.
+1 @Gianni, rvalues peut être ni
const
nivolatile
. Ce serait même moyen s'ils pourraient l'être?Les nombres imaginaires? en.wikipedia.org/wiki/Imaginary_number
bon pour l'avertissement 1, ont maintenant un coup d'oeil à la question de la mise en garde 2, les arguments sont des pointeurs
J'ai essayé votre édité échantillon sur Visual Studio 2008; il renvoyait un message d'erreur disant que la conversion de
COUNT *
àint *
n'est pas possible (j'ai compilé le code en C++, pas du C). J'ai été en mesure de corriger de 2 façons: 1 - changer functionTwo() définition deint functionTwo( COUNT *number )
2 - cast l'argument explicitement (comme je l'ai mentionnée dans mon post original)count = functionTwo( (int *)&number );
OriginalL'auteur Praetorian
Si je compile
à l'aide de
Je ne reçois pas tous les avertissements. J'ai essayé de gcc 4.0, 4.2, 4.3 et 4.4. Votre warningTwo sonne comme vous êtes de passage à pointeurs, et non des valeurs, et c'est une autre histoire...
EDIT:
Votre dernier exemple devrait être écrit comme ceci, de nouveau, pas de mises en garde:
EDIT:
Si vous ne pouvez pas modifier functionTwo:
Remarque que tout accès à un volatile variable est "spécial". Dans la première version avec
functionTwo(COUNT *number)
, functionTwo sait comment y accéder correctement. Dans la deuxième version avec countcopy, la fonction principale sait comment y accéder correctement lors de l'attribution countcopy = copie.c'est ok pour un int, mais si vous avez un tableau, il n'est pas efficace en terme de mémoire pour faire une copie simplement pour éviter un avertissement
Il n'est pas question de "comment éviter les mises en garde", c'est à propos de l'exactitude. 🙂 Avec une copie explicite, vous aurez le droit de la sémantique (quel qu'il arrive à dire de la mise en œuvre), et vous savez exactement où vous avez lu ou accès en écriture à la volatilité des objets. Si vous prenez juste un pointeur, jeter le "volatile", qualificatif, et de le transmettre à une fonction de la bibliothèque, tous les paris sont éteints (comportement indéfini).
vous êtes en droit qui est sur le point de savoir quand vous lecture/écriture volatile objets. donc reste à voir si il y a une autre façon, parce que si il n'y a pas d'autre moyen, dans le cas d'un tableau, c'est une mémoire des déchets
OriginalL'auteur Jukka Suomela
Il est possible que ceux qui ont écrit qu'il voulait être sûr que toutes les opérations sont atomiques et a déclaré que toutes les variables int comme volatile (c'est un MT de l'application avec une mauvaise synchronisation?), donc tous les entiers à partir du code sont déclarées comme volatile "pour des raisons de cohérence".
Ou peut-être en déclarant le type de fonction que l'instabilité qu'ils s'attendent à arrêter les optimisations des appels répétés pour les fonctions pures? Une incrémentation d'une variable statique à l'intérieur de la fonction serait de le résoudre.
Cependant, essayer de deviner leur origine, l'intention, parce que cela n'a tout simplement aucun sens.
netrino.com/node/80
vous vous trompez peut-être, si vous n'var = var + 1 et var n'est pas volatile, alors il peut être modifié dans le milieu de l'opération à l'intérieur d'une interruption de service de routine (pour l'embarqué) ou d'un fil, et puis si le compilateur ne lisent pas réel var mise à jour de la valeur, l'opération qui pourrait être var = var(mise à Jour) + 1, perdra de l'atomicité de faire var = var(NoUpdated) + 1, et la valeur mise à jour sera perdu
OriginalL'auteur ruslik