Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting twice in the same line

Tags:

c

casting

I saw this code in project.

b's type is void*:

void *b = ...;
int a = (int) (unsigned long) b;

Is this line pointless? I mean, it this same as a = (int) b in all cases?

like image 484
BufBills Avatar asked Jun 18 '13 05:06

BufBills


2 Answers

This probably avoids a compiler warning on 64-bit Unix systems where unsigned long is a 64-bit quantity and hence big enough to hold a pointer, but int is a 32-bit quantity that is not big enough to hold a pointer. The cast to (unsigned long) preserves all the bits of the address; the subsequent cast to int throws away the high-order 32-bits of the address, but does so without getting a warning by default.

To demonstrate:

int main(void)
{
    void *b = (void *)0x12345678;
    int   a = (int)(unsigned long)b;
    int   c = (int)b;
    return a + c;
}

$ gcc -O3 -g -std=c99 -Wall -Wextra -c ar.c
ar.c: In function ‘main’:
ar.c:5:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
$

Using GCC 4.7.1 on Mac OS X 10.8.4, defaulting to 64-bit compilation.

It is interesting to speculate what will be done with the 'part of an address' value.

like image 192
Jonathan Leffler Avatar answered Nov 13 '22 16:11

Jonathan Leffler


Directly typecasting to pointer to smaller type say int may result in compilation error on some compiler (like Clang) under x64 bit environment.

For example:

 void *p = GetSomeAddress;
 int i = (int)p;  //error on compilers like Clang.

Solution is:

int i = (int)(unsigned long)p;

or

int i = (int)(long)p;

This is because, on Unix, under LP64 model, long is 64-bit.

Such cases, you need to look thoroughly that why you need typecast from pointer to int or other smaller type which can result in loss of the data.

This question may also help you. How should I handle "cast from ‘void*’ to ‘int’ loses precision" when compiling 32-bit code on 64-bit machine?

like image 40
doptimusprime Avatar answered Nov 13 '22 18:11

doptimusprime