Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsafe conversion

Is the following conversion safe?

int b[10][10];
char *x;
int a[]={0,1,2,3,4,5,6,7,8,9};

for(int i=0;i<10;i++)
  for(int j=0;j<10;j++)
    b[i][j]=a[i];

for(x=(char *)&b[0];x<=(char *)&b[9][9];x+=sizeof(a+1)) // Problem lies here!
    printf("%d\n",*x);

I don't think the above conversion in the for loop is safe (I think it is platform dependent). Please correct me if I am wrong. I am surprised because the code compiles without giving any warnings even when compiled using the -Wall -pedantic options in gcc.

like image 319
Prasoon Saurav Avatar asked Feb 06 '10 02:02

Prasoon Saurav


1 Answers

This whole thing has a chance of being legal for one and only one reason: the 2D int array object is reinterpreted as an array of char objects. While in general case memory reinterpretation leads to undefined behavior, the language specification explicitly allows "array of [signed/unsigned] char" reinterpretations for objects of any type.

However, one formal safety problem is still there. The language does not guarantee that any bit pattern is a valid value of char type. Your attempt to read reinterpreted memory through char type can theoretically cause undefined behavior if it encounters trap representation for char. In order to be safe here you have to use the unsigned char type, which is the only type that has no trap representations. Of course, a platform with a trapping char can be safely called "exotic".

Meanwhile, your sizeof(a + 1) doesn't seem to make any sense. a + 1 is an expression of int * type. Why you'd want to use the pointer size to increment your x value in this case is not clear to me. What were you trying to achieve?

As for the absence of warnings... I wouldn't expect the compiler to issue any warnings here. GCC often warns about type-punning (aka memory reinterpretation), but since char reinterpretations are explicitly allowed (as I said above), there's no warning here. Moreover, explicit casts usually tend to suppress any warnings, since they are a way of telling the compiler that you do actually want to do something regardless of how wrong and/or dangerous it might be.

like image 52
AnT Avatar answered Sep 22 '22 13:09

AnT