简体   繁体   中英

what is the role of x = (char *)&a and what does it do?

I have this piece of code:

int a;
char *x;
x = (char *) &a;
a = 512;
x[0] = 1;
x[1] = 2;
printf("%d\n");
return 0;

This prints 513 . Please explain and especially line 3.

Line 3 simply points x to the address of a . As a special rule in C, we are allowed to use character pointers specifically to access individual bytes of any other variable.

Further access of x will change individual bytes of a , in a way that depends on CPU endianess. On a little endian machine, 512 = 0x200, where the two least significant bytes have the values 0x00 and 0x02 respectively. x[0] = 1; changes the lowest byte to 0x01, and x[1] = 2; writes value 0x02 to the byte that already contained 0x02. The result will be 0x201 = 513 decimal.

The problem here is that printf("%d\\n"); invokes undefined behavior, since it contains an incorrect amount of parameters.

Summary: the code is gibberish and the C language doesn't define what this program will do. It may crash, print any value or print no value at all. Pondering about why it behaves in a certain way isn't meaningful practice. Instead focus on learning how to avoid undefined behavior bugs.

As long as int is larger than char on the specific machine (and by the C standard it must be), your byte-wise access itself is not undefined. Endianess can be determined. Type sizes can be determined using sizeof.

What you are really doing here is set specific bytes (x in your code is a char pointer; the array notation [] allows you to access individual bytes within your integer) of your integer value to some bit patterns. The endianess of your machine will determine what these bit patterns represent if you access the thus modified bytes again as an integer.

As long as you don't write to a byte that is not part of the original integer, the code is not incorrect, except for the missing argument in the call to printf which is truly UB.

The question which remains is what purpose such a manipulation might serve. But there are uses for this technique.

Let's assume You are on a machine where an int has 4 bytes. 512 in hex format would be '00 00 02 00'. On a little endian processor the pointer points to the lowest significant byte. To set every byte individually the pointer to int is casted to a pointer to char: x = (char *) &a; as a char is always coded in one byte. Now the four bytes are treated as an array of four bytes. The lowest significant byte is set to '1' by x[0] = 1; The next byte is set to '2' (is it anyway, so the line x[1] = 2; could be skipped) and byte 3 and 4 are untouched 00 and 00. 'a' is now '00 00 02 01' or 513. Of course in the printf statement 'a' is missing: printf("%d\\n",a);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM