Plusieurs réponses ont pointé vers uintptr_t
et #include
comme étant 'la' solution. C'est, je suggère, une partie de la réponse, mais pas toute la réponse. Vous devez également examiner l'endroit où la fonction est appelée avec l'ID de message de FOO.
Considérez ce code et cette compilation :
$ cat kk.c
#include
static void function(int n, void *p)
{
unsigned long z = *(unsigned long *)p;
printf("%d - %lu\n", n, z);
}
int main(void)
{
function(1, 2);
return(0);
}
$ rmk kk
gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \
-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk
kk.c: In function 'main':
kk.c:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast
$
Vous observerez qu'il y a un problème à l'emplacement de l'appel (dans main()
) — convertir un entier en pointeur sans cast. Vous devrez analyser votre function()
dans toutes ses utilisations pour voir comment les valeurs lui sont passées. Le code à l'intérieur de ma function()
fonctionnerait si les appels étaient écrits :
unsigned long i = 0x2341;
function(1, &i);
Comme les vôtres sont probablement écrits différemment, vous devez examiner les points où la fonction est appelée pour vous assurer qu'il est logique d'utiliser la valeur comme indiqué. N'oubliez pas, vous pourriez trouver un bug latent.
De plus, si vous souhaitez formater la valeur du paramètre void *
(une fois convertie), regardez attentivement l'en-tête (au lieu de stdint.h
— inttypes.h
fournit les services de stdint.h
, ce qui est inhabituel, mais la norme C99 dit que [t]he header includes the header and extends it with additional facilities provided by hosted implementations) et utilisez les macros PRIxxx dans vos chaînes de format.
En outre, mes commentaires s'appliquent strictement au C plutôt qu'au C++, mais votre code fait partie du sous-ensemble de C++ qui est portable entre C et C++. Il est fort probable que mes commentaires s'appliquent.
5 votes
Je sais que cela ressuscite un ancien post, mais il semble que la réponse acceptée ne soit pas tout à fait correcte. Un exemple concret de
size_t
ne fonctionnant pas est la mémoire segmentée i386. Bien qu'il s'agisse d'une machine 32 bits,sizeof
retourne2
poursize_t
. La réponse de Alex ci-dessous semble correcte. La réponse d'Alex etuintptr_t
fonctionnent presque partout et c'est désormais standard. Il offre un traitement C++11, et il donne même les protections de l'en-tête C++03.