What does this C ++ construct do?

Somewhere in the lines of code I came across this construction ...

//void* v = void* value from an iterator
int i = (int)(long(v))

      

What possible purpose could it serve?

Why not just use it int(v)

instead? Why cast to long

first?

+2


a source to share


2 answers


This will most likely turn off warnings.

Assuming a 32 bit architecture with sizeof (int) sizeof (long) and sizeof (long) == sizeof (void *), you might get a warning if you cast void * on an int and don't get a warning if you cast void * until you truncate. Then you get a warning assigning a long to an int (possible truncation) which gets removed and then explicitly cast from long to int.



Without knowing the compiler, it's hard to tell, but I've certainly seen the multi-step throws needed to prevent warnings. Why not try converting the construct to what you think it should be and see what the compiler says (of course, this will only help you figure out what was in the original programmer's mind if you use the same compiler and same warning level as they were).

+8


a source


This is eeevil.

In most architectures, a pointer can be thought of as just another number. Most architectures have long

as many bits as a pointer, so long

there is a 1-to-1 map between values and pointers. But violations, especially of the second rule, are not uncommon!

long(v)

is a pseudonym for reinterpret_cast<long>(v)

which does not carry any guarantees. Not suitable for any purpose unless your ABI specification says otherwise.



However, for whatever reason, someone who wrote this code prefers int

before long

. So they cross their fingers again and hope that no significant information is thrown out in the bits that might be lost as a result of dropping int

to long

.

Two uses of this are creating a unique identifier for an object, or trying to somehow remove a pointer to some arithmetic not otherwise supported by pointers.

  • An opaque identifier can be void*

    , so a cast to integral type is not required.
  • "Extracting" an integer from a pointer (such as a division operation) can always be done by subtracting the underlying pointer to get the type difference ptrdiff_t

    , which is usually long

    .
+3


a source







All Articles