Type casting char pointer to integer pointer
Asked Answered
B

2

5

So I saw a few example on how the endianness of an architecture could be found. Let's say we have an integer pointer that points to an int data type. And let's say the int value is 0x010A0B12. In a little endian architecture, the least significant byte, i.e, 12, will be stored in the lowest memory address, right? So the lowest byte in a 4-byte integer will be 12.

Now, on to the check. If we declare a char pointer p, and type cast the integer pointer to a char * and store it in p, and print the dereferenced value of p, we will get a clue on the endianness of the architecture. If it's 12, we're little endian; 01 signifies big endian. This sounds really neat...

int a = 0x010A0B12;
int *i = &a;
char *p = (char*)i; 
printf("%d",*p); // prints the decimal equivalent of 12h!

Couple of questions here, really. Since pointers are strongly typed, shouldn't a character pointer strictly point to a char data type? And what's up with printing with %d? Shouldn't we rather print with %c, for character?

Binturong answered 19/2, 2016 at 2:0 Comment(1)
Related : stackoverflow.com/questions/34826036/…Suneya
W
7

Since pointers are strongly typed, shouldn't a character pointer strictly point to a char data type?

C has a rule that any pointer can be safely converted to char* and to void*. Converting an int* to char*, therefore, is allowed, and it is also portable. The pointer would be pointing to the initial byte of your int's internal representation.

Shouldn't we rather print with %c, for character?

Another thing is in play here: variable-length argument list of printf. When you pass a char to an untyped parameter of printf, the default conversion applies: char gets converted to int. That is why %d format takes the number just fine, and prints it out as you expect.

You could use %c too. The code that processes %c specifier reads the argument as an int, and then converts it to a char. 0x12 is a special character, though, so you would not see a uniform printout for it.

Wherewithal answered 19/2, 2016 at 2:6 Comment(2)
Thanks, although, what's the "untyped parameter of printf" that you're talking about?Binturong
@Binturong Three dots ... at the end of print's signature, i.e. int printf ( const char * format, ... ) specify that you can pass additional arguments of any type.Wherewithal
B
-1

Since pointers are strongly typed, shouldn't a character pointer strictly point to a char data type?

This is kind of undefined behavior - but such that most sane implementations will do what you mean. So most people would say ok to it.

And what's up with printing with %d?

Format %d expects argument of type int, and the actual arg of type char is promoted to int by usual C rules. So this is ok again. You probably don't want to use %c since the content of byte pointed by p may be any byte, not always a valid text character.

Brame answered 19/2, 2016 at 2:9 Comment(4)
I am dereferencing it, so clearly %p isn't what I'm looking for right?Binturong
@nirvanaswap: yes, sorry, I've edited this. To dasblinkenlight: There is undefined behavior, it is assumption that any byte in memory can be individually addressed and accessed. Usually this is true, but imagine that OP attempts to access a middle byte in (say) 32-bit hardware register that can be read only as whole 32 bit and at aligned address only. It will cause runtime exception.Brame
this is quite wrong. it is always valid to address object memory by char *; the most basic memcpy implementations do this.Jegar
Yes it may be valid for a C program to address any pointer if the compiler is happy with this. But the hardware has its rights to act up and throw an exception.Brame

© 2022 - 2024 — McMap. All rights reserved.