Je supprime les avertissements gcc d'un code hérité.
Est-il possible de supprimer l'avertissement "cast to pointer from integer of different size" via le transtypage:
example:
some_struct *ptr = func() // func() returns an integer.
Quelqu'un peut-il me guider pour résoudre ces avertissements gcc?
Tout d'abord, si vous pouvez corriger func
(êtes autorisé à modifier sa source), corrigez-le. Si ses calculs peuvent être effectués avec des pointeurs, faites-les avec des pointeurs et des pointeurs de retour. Parfois, il existe des raisons valables de travailler avec des adresses sous forme d'entiers (par exemple, pour traiter les problèmes d'alignement dans un code spécial). Dans ce cas, modifiez func
pour utiliser le type uintptr_t
(Défini dans stdint.h
). Il est conçu pour traiter les pointeurs comme des entiers lorsque cela est nécessaire. (Il y a aussi intptr_t
Si l'arithmétique signée est meilleure pour une raison quelconque, mais je trouve généralement que le uintptr_t
Non signé est moins gênant.) De préférence, func
devrait convertir le uintptr_t
Vers un pointeur lors de son renvoi, donc le type de retour de func
serait un pointeur (vers quelque chose, peut-être some_struct
Ou void
).
Si vous ne pouvez pas corriger func
, vous pouvez utiliser des transtypages pour indiquer au compilateur que vous avez l'intention d'effectuer les conversions en cours. Cependant, ce message d'erreur particulier vous indique que vous ne convertissez pas simplement un entier en un pointeur, mais que vous convertissez un entier d'une taille (par exemple, quatre octets) en un pointeur d'une autre taille (par exemple, huit octets). Il est probable que ce code a été écrit à l'origine pour un système où le type entier renvoyé par func
avait la même taille que le type de pointeur, mais vous compilez maintenant sur un système où le type de pointeur est plus grand ou moins que celui taille entière.
Dans ce cas, vous devez vous assurer que le calcul effectué par func
fonctionne dans la nouvelle architecture. S'il ne renvoie qu'une valeur 32 bits, est-ce que cela conservera toujours la valeur correcte? Autrement dit, rien ne sera perdu par les 32 bits hauts manquants? Aucune adresse que func
doit calculer ne dépasse jamais la valeur maximale du type entier qu'il utilise? Si func
utilise des types entiers signés, considérez également le bit de signe.
Si vous vous êtes assuré que la valeur renvoyée par func
est correcte, vous pouvez utiliser des transtypages explicites, tels que: some_struct *ptr = (some_struct *) (intptr_t) func();
.
Mon gcc ne donne pas l'avertissement que vous avez cité. Ce serait aussi étrange car il n'y a pas de cast dans votre code.
Je reçois l'avertissement
assignment makes pointer from integer without a cast
Notez la partie "sans plâtre". Ainsi, vous pouvez rendre gcc silencieux en castant (sans changer le comportement):
some_struct *ptr = (void*)func();
Ensuite, vous obtiendrez votre avertissement ("transtypé en pointeur à partir d'un entier de taille différente") si le type de retour de func
ne convient pas aux adresses. Cela peut être réduit au silence en convertissant en outre func()
en un type entier approprié, par ex. intptr_t
:
some_struct *ptr = (void*)(intptr_t)func();
Tout cela sous l'hypothèse que vous voulez vraiment convertir l'entier de mauvaise taille en un pointeur. Probablement, retravailler le code est une meilleure idée.
Il y a deux possibilités ici:
func
transforme un pointeur réel en un entier; il est ensuite utilisé comme pointeur.func
renvoie un entier qui est stocké dans un pointeur; ptr
est ensuite converti en entier et utilisé comme entier.Dans le premier cas, la valeur de retour de func
va perdre des informations , et potentiellement planter ou pire, si int
est plus petit que la taille d'un pointeur de données, ce qu'il sera sur la plupart modèles de mémoire 64 bits (y compris Windows et Linux). Dans ce cas, vous devez changer le type de retour de func
en intptr_t
; voir tiliser intptr_t au lieu de void *? et Pourquoi/quand utiliser `intptr_t` pour le transtypage en C? .
Dans le second cas, c'est moins un problème, mais pour traiter les problèmes d'endianité, vous devez transtyper via intptr_t
: some_struct *ptr = (some_struct *)(intptr_t)func();
et plus tard int value = (int)(intptr_t)ptr;
. Voir Macros de conversion de type GLib pour une discussion du problème.