embedc
embedc

Reputation: 1665

What is the best way to compare uintptr_t and a pointer type?

Is it just the reinterpret_cast?

int *pointer;
uintptr_t value;
value == reinterpret_cast<uintptr_t>(pointer);

Upvotes: 3

Views: 1275

Answers (2)

Depends on your goal really.

[expr.reinterpret.cast]

4 A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined. [ Note: It is intended to be unsurprising to those who know the addressing structure of the underlying machine.  — end note ] A value of type std​::​nullptr_­t can be converted to an integral type; the conversion has the same meaning and validity as a conversion of (void*)0 to the integral type.

5 A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.

The mapping is implementation defined (obviously). If you wish to check that the value of pointer was used to initialize value, then your check is insufficient. The above doesn't promise that reinterpret_cast<uintptr_t>(pointer) will always yield the same integer, even though all sane implementations today do.

I would do the check in reverse, since we have a round trip guarantee:

reinterpret_cast<int*>(value) == pointer;

But even then, it's a pretty weak guarantee. I would not faff about with these conversions too much if I were you. It may be worth to reconsider your design.

Upvotes: 4

Bathsheba
Bathsheba

Reputation: 234735

If you follow the standard to the letter, you ought to use

value == (uintptr_t)(void*)pointer

or using reinterpret_cast:

value == reinterpret_cast<uintptr_t>(reinterpret_cast<void*>(pointer))

which personally I find less readable. Naturally the compiler will remove all the "fluff".

Upvotes: 2

Related Questions