简体   繁体   中英

Integer to Void * ? What is the best way

I've seen many topics about typecasting integers into void * but I still have trouble understanding why it works without casting them, and why solving these warnings are so time-consuming, at least the way I see it.

I tried to make this topic as small as possible but trying to explain everything, but I think explaining the steps I did, how I was trying to do it, etc.. is much easier for people to understand my issue.

I'm working with linked lists and my structure is:

typedef struct list_t {
    struct list_t *prev;
    void *data;
    struct list_t *next;
}list_s;

In the beginning, I simply set the data type as an integer, because I would always use integers in my program. My only problem was if I wanted to set the data value to NULL to check if there was something in my linked list (if I already used it once).

Some people would say "just set it to zero" but I could have a zero-value in my list, so there could be an error at some point.

I thought about just setting a variable such as "has_list_been_already_used" or something like that but I think that it would just make my code way bigger just for nothing.

My first thought after having this warning:

warning: assignment to 'void *' from 'int' makes pointer from integer without a cast

was: "oh I'll just cast it to void * like (void*)my_atoi(datastring); and that's it.

but I got another warning:

warning: cast to pointer from integer of different size

At this point, I didn't know what to do and didn't really find any issue to typecast this way. On the other hand, I've found another way of doing it, but I wonder if this is the right thing to do and if there is another way that doesn't lead to modifying almost all of my code and expanding it. Let me explain:

Someone said that you could just cast integers to void * this way:

int x = 10;
void *pointer = &x;

and retrieving it in the code such as:

int y = *((int *) pointer);

In my code, everywhere I would be retrieving my data from my structure, I will always have to do it this way.

Is that really the only option I got? And why just type-casting it from an integer to a void* doesn't do the job, especially if it "works well", but indeed, have warnings.

Thanks.

Typecasting pointer usually doesn't do anything internally. It however tells your compiler that is is to treat the pointer as a typed pointer.

So a pointer is literally that. It points to a place in memory. And what type of object is stored at that place is not always known. You can tell your compiler that it is an integer by casting: ( int* iptr = (int*) voidptr ) Now your compiler will read the memory location pointed to by the pointer as if it was an integer. If it was not an integer, you will get garbled data.

Now this example:

int x = 10;
void *pointer = &x;

This is ok, because you say "make a pointer (to anything) form this pointer to an int" Which is ok, because a pointer to an int always points to anything. But if you do it the other ways you have to explicitly say that you are sure there is an int stored there, because the compiler doesn't know.

If you want, you can just make a linkedlist of integers. Then you don't even need to use pointers. Just put the integer in the struct instead of the void* . The reason this linkedlist structure is written this way, is that it allows for any type of data, or data structure to be used. This is why they added stuff like templating in c++. ( But we are talking c now)

The proper c way to do it would probably be to make a macro like

#define declare_LL_type(type) ...

Which would make a custom typed linkedlist struct definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM