Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding void* against intptr_t and uintptr_t

This is the code I'm testing:

int value = 0;
void* addyvoid = static_cast<void*>(&value); // C++-style cast.

it works perfectly, but I could use uintptr_t / intptr_t. But they are not good for holding pointers as people said here because they are too big. So, is this true? If yes, however, for holding pointers using void* would be better, but will there be a loss of data?

like image 924
ScottPerez Avatar asked Dec 02 '16 22:12

ScottPerez


People also ask

What does Uintptr_t mean?

uintptr_t is an unsigned integer type that is capable of storing a data pointer. Which typically means that it's the same size as a pointer. It is optionally defined in C++11 and later standards.

What is a void pointer?

The void pointer in C is a pointer that is not associated with any data types. It points to some data location in the storage. This means that it points to the address of variables. It is also called the general purpose pointer. In C, malloc() and calloc() functions return void * or generic pointers.

What is the use of Uintptr_t?

The intptr_t and uintptr_t types are extremely useful for casting pointers when you want to do address arithmetic. They should be used instead of long or unsigned long for this purpose. Use of uintptr_t for casting is usually safer than intptr_t , especially for comparisons.

What's the point of pointers in C?

The Pointer in C, is a variable that stores address of another variable. A pointer can also be used to refer to another pointer function. A pointer can be incremented/decremented, i.e., to point to the next/ previous memory location. The purpose of pointer is to save memory space and achieve faster execution time.

Why should I avoid intptr_t and uintptr_t types?

The size of intptr_t and uintptr_t isn't a good reason to avoid them. They're just for different applications. If you need to do numeric computations on pointers, use those types. Otherwise, if you just need to store "a pointer to something," use a void*.

Why do we use intptr_t instead of int for numeric values?

In those cases, when you need to work with the numeric value of a pointer, intptr_t and uintptr_t are integer types that (if they exist) are guaranteed to be large enough to hold any pointer. This is not true of, say, int, since int 's size relative to pointer sizes isn't specified.

Is it safe to cast from void to intptr_t?

That cast is guaranteed to work and the conversion from void* back to the original type only requires a static_cast and is guaranteed to be safe. The size of intptr_t and uintptr_t isn't a good reason to avoid them.

Why does C++ require reinterpret_cast to convert int to intptr?

This is not true of, say, int, since int 's size relative to pointer sizes isn't specified. Because it's fundamentally unsafe to do these conversions, C++ requires that you use reinterpret_cast to convert to and from intptr_t and uintptr_t and pointer types.


1 Answers

The purpose of intptr_t and uintptr_t is that in some applications, you actually do need to do some sort of numeric computation on pointer values, perhaps by flipping individual bits, perhaps by XORing them, etc. In those cases, when you need to work with the numeric value of a pointer, intptr_t and uintptr_t are integer types that (if they exist) are guaranteed to be large enough to hold any pointer. This is not true of, say, int, since int's size relative to pointer sizes isn't specified.

Because it's fundamentally unsafe to do these conversions, C++ requires that you use reinterpret_cast to convert to and from intptr_t and uintptr_t and pointer types.

If all that you're doing is storing "a pointer to something," and provided that pointer isn't a function pointer or a member function pointer, you can just cast it to void*. That cast is guaranteed to work and the conversion from void* back to the original type only requires a static_cast and is guaranteed to be safe.

The size of intptr_t and uintptr_t isn't a good reason to avoid them. They're just for different applications. If you need to do numeric computations on pointers, use those types. Otherwise, if you just need to store "a pointer to something," use a void*.

like image 110
templatetypedef Avatar answered Sep 26 '22 13:09

templatetypedef