Je veux réinterpréter jeter un pointeur de fonction dans une variable Void *. Le type du pointeur de fonction sera de type ci-dessous est le code d'échantillon, p> Le code ci-dessus fonctionne bien avec les compilateurs Visual Studio / X86. Mais avec le compilateur de bras, il donne une erreur de compilation. Je ne sais pas pourquoi. P> erreur: # 694: Reterpret_cast ne peut pas
jeter const ou autre type
qualificatifs p>
blockQuote> J'ai lu l'explication dans casting d'un pointeur de fonction à un autre Tapez P> J'étais préoccupé par l'explication ci-dessous. P> Casting entre les pointeurs de la fonction et
Pointeurs réguliers (par exemple, casting d'un Comment faire de telles conversions de classe * (*) (vide *) code>.
void
(*) (void) code> à un
vide * code>). Une fonction
Les pointeurs ne sont pas nécessairement les mêmes
taille comme des pointeurs réguliers, depuis sur
certaines architectures qu'ils pourraient contenir
informations contextuelles supplémentaires. Cette
va probablement fonctionner ok sur x86, mais
rappelez-vous que c'est un comportement indéfini. P>
blockQuote>
Void (*) (vide *) -> Void * code> efficacement de sorte qu'il compile presque la même chose dans la plupart des compilateurs? P > p>
5 Réponses :
en C, la distribution est autorisée, mais c'est un comportement Isn 't défini (c.-à-d. Un aller-retour n'est pas garanti de travailler). p> Certaines fonctions POSIX ont besoin de la conversion pour être bien utiles. P> J'ai joué avec plusieurs compilateurs que j'ai ici: p> dans le dernier brouillage disponible pour C ++ 0x, le Notez que si cela a du sens. ou ne dépendra pas de la cible plus que le compilateur: un compilateur portable comme GCC aura un comportement imposé par l'architecture cible et éventuellement abi. p> comme d'autres ont fait la remarque, P> reterpret_cast code> ne peut pas être utilisé pour lancer un pointeur pour fonctionner à un
vide * code>. Bien qu'il y ait quelques autres choses supplémentaires qu'un CAST C peut faire ce qui n'est pas autorisé par une combinaison d'une combinaison de jeux statiques, de réinterpret et de const, cette conversion n'est pas l'une d'entre elles.
REINIERPRET_CAST CODE> entre les pointeurs de fonction et les pointeurs d'objets est pris en charge sous condition. P>
Test* *p(void **a);
(Près de -1) Je ne pense pas que cela a raison, pouvez-vous fournir une référence pour cela? Je crois comprendre que C-style Cast est défini en termes de nouveaux styles de distribution. Par conséquent, s'il n'est pas possible de le faire à l'aide de Reterpret_cast, il n'est pas possible avec une mise en forme de style C.
ne devrait pas Peut-être que c'est votre problème? P> test * * p (vide ** a); code> être
test * (* p) (vide ** a) p>? P>
Test * p (void a) est également résolu à taper le test * ( i>) (void b>) .. Donc, je pense que les deux représentations sont valides. Je suis sûr de cela parce que j'ai essayé de cette façon aussi ..
Si vous cherchez simplement à stocker différents types de pointeur de fonction dans une liste, vous pouvez vous lancer sur un type de pointeur de fonction commun: ceci est valide pour faire via Un pointeur sur une fonction peut être explicitement converti en un pointeur à une fonction d'un type différent. L'effet d'appeler une fonction via un pointeur à un type de fonction (8.3.5) qui n'est pas identique au type utilisé dans la définition de la fonction est indéfinie. Sauf que de convertir une rvalue de type "pointeur en T1" au type "pointeur en T2" (où T1 et T2 sont des types de fonction) et que le type d'origine donne la valeur de pointeur d'origine, le résultat d'une telle conversion de pointeur est indéterminée . p>
blockQuote> p> Reterpret_cast Code> (5.2.10 / 6): P>
réinterpret_cast ne peut être utilisé que pour p>
reterpret_cast (x) code> est équivalent à * reterpret_cast (& x) code> (à l'aide de et code> et code> et < Code> * code>) Chaque fois que la deuxième coulée est possible en utilisant les règles ci-dessus. LI>
ul>
(voir la section 5.2.10 de la norme) P>
Cela signifie notamment qu'un déclencheur d'un pointeur pour fonctionner à Void * code> n'est pas possible, mais vous pouvez le jeter à void (*) () code>. < / p>
edit (2017): strong> La réponse ci-dessus n'est correcte que pour C ++ 03. En C ++ 11 à C ++ 17, il s'agit de la mise en œuvre de la mise en œuvre si les conversions entre les pointeurs de fonction et void * code> sont autorisés. Ceci est généralement le cas sur les systèmes compatibles POSIX car dlsym () code> est déclaré pour renvoyer Void * code> et les clients sont attendus à REINIERPRET_CAST CODE> Type de pointeur de fonction correct. P>
voir CPPreference.com pour la liste complète des conversions autorisées. < / p>
D'autres ont souligné que vous ne pouvez pas faire ce casting (fortement parlant, casting à Je fais habituellement ce qui suit, ce qui fait un type de jeu de mots, et est la façon recommandée de le faire, selon le manuel de la distribution intermédiaire à J'ai constaté que l'utilisation de cette technique, GCC remarque automatiquement quand la gauche et les bons types diffèrent de taille et crachent un avertissement dans ce cas. Inutile de dire que comme avec toutes les techniques qui tentent de contourner cette limitation, ceci est un comportement indéfini. p> Si vous avez une fonction, et que vous voulez un le truc sur Commencez à être capable de faire le type mais consiste à transformer le pointeur de fonction temporaire sur une référence de LValue à la const, que vous pouvez prendre l'adresse, puis procéder comme ci-dessus. P> Utilisation de style C ++ explicite Void * code> tout que vous utilisez
Reterpret_cast CODE> n'est pas autorisé - mais silencieusement toléré par les compilateurs.
static_cast code> est destiné à être utilisé ici).
dlopen code> (qui consiste à faire la casting converse - Casting de em>
void * code> to em> un pointeur de fonction). Prendre l'adresse du pointeur de fonction vous donnera un pointeur de données: pointeur sur un pointeur de fonction. Cela vous permettra de le jeter à
Void * code>. Il prétend qu'il préconise un
vide * code> (au lieu d'un pointeur de fonction), puis la lit. p>
vide * code> équivaut à utiliser deux
static_cast code> s en interne et que GCC soit silencieux sur l'avertissement d'un type de jeu de mots. Utilisation de C ++ Style CastS, cela ressemble à une combinaison de deux
static_cast code> 's p>
void * code> en pointant dessus, vous pouvez le faire tout en une seule ligne, mais c'est un peu lourd sur la syntaxe. Voici comment cela peut être fait, mais je ne le recommande pas si vous avez des problèmes pour le lire - vous pouvez toutefois l'utiliser à l'intérieur d'une macro p>
Static_cast CODE> CASTS, Ceci semble beaucoup plus compliqué, car vous devez en tenir compte de la constitution. Le style C a choisi automatiquement de cela. Amusez-vous! P>
int main() {
Test** pF(void **a);
void *p = *static_cast<void* const*>(
static_cast<void const*>(
&static_cast<Test** (* const&)(void **a)>(&pF)));
}
Merci pour cela - le code fait crawler mes globes oculaires, mais il semble fonctionner correctement et éviter les avertissements / erreurs même avec des niveaux d'avertissement maximum sur GCC et Scrang.
Vous devriez au moins mettre dans une affirmation selon laquelle
tailleOf (vide *)> = Tailleof (test ** (*) (NOID **)) code>. Si cela affirme échoue, il n'existe évidemment aucun moyen de stocker le pointeur de la fonction dans un
vide * code>. Si l'affirmation n'a pas échoué, cela ne garantit toujours rien, mais au moins il est possible que la distribution puisse fonctionner.
Notez que P a en fait un test de type ** (void **), et est une fonction, pas un pointeur de fonction. Mettre un espace dans "
test * * code>" n'affecte pas l'analyse.