Compiler warning - different from pointer to integer of different sizes

I am trying to create a structure that can contain common values. The code below works, but I get a compiler warning about casting from pointer to integer. This is on a 64 bit system.

struct node { void *key; void *value; }; void insert(struct node *ht, void *key, void *value) { ht->key = key; ht->value = value; return; } int main() { struct node *t = (struct node *)malloc(sizeof(struct node)); insert(t, (void *)3, (void *)5); printf("[%d]->[%d]\n", (int)t->key,(int)t->value); free(t); return 0; } 

I'm not even sure if this is the right way. I somehow cracked it. Please let me know if there is a right way to do this.

+4
source share
3 answers

The compiler is trying to warn you that you lose bits when dropped from void * to int . He does not know that void * is actually distinct from int , so the lost bits are meaningless.

A double throw will enable this (int)(uintptr_t)t->key .
First it drops void * to uintptr_t (same size, no warning), then uintptr_t to int (number to number, no warning).
You need to include <stdint.h> to be of type uintptr_t (an integer type with the same size as the pointer).

+7
source

It is useful to remember that in a 64-bit system, a pointer is a 64-bit value [memory address.]

int is just a 32-bit value, no matter what architecture you are in. Each time you try to assign a 64-bit value to a 32-bit value without casting it explicitly, the compiler will generate a warning [provided, it can still work, but overall this is not good practice.]

If you don't mind using unsigned integers, it might be easier to use uint_64t or something like that, which will avoid assignment from 64-bit and 32-bit (uint_64t is an unsigned 64-bit int)

Hope this helps.

One thing you can do is:

 int key = 3; int value = 5; insert(t, (void *) &key, (void *) &value); printf("[%d]->[%d]\n", (int) *(t->key), (int) *(t->value)); 

However, be very careful when doing such things. It is not possible to know exactly what value is stored by this pointer unless you can guarantee that you will set the pointer and the value / type does not change. Unless you add an enumeration field or something that stores the type of value stored in the pointer's location, but this view defeats the target.

+3
source

You have a lot of problems with the code you posted.

Firstly:

 printf("[%d]->[%d]\n", (int)t->key,(int)t->value); 

When printing pointers, print pointers. Use% p. See here:

http://www.cplusplus.com/reference/cstdio/printf/

Secondly:

 insert(t, (void *)3, (void *)5); 

I'm not sure what you expected, but you store ADDRESS, not VALUE. (i.e. you set your key as a pointer to the contents of address 3, and the value as a pointer to the contents of address 5).

Third:

 struct node *t = (struct node *)malloc(sizeof(struct node)); 

Here you selected node, but you didn’t allocate anything to store the content. Your node just contains a few pointers (ADDRESSES), it does not contain any values. I am not sure if this is what you want.

Finally, your compiler is right to warn you. There is a chance that you lose accuracy. As @JonathanLeffler said, use uintptr_t.

+2
source

All Articles