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?

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
nirvanaswap
  • 859
  • 2
  • 11
  • 21
  • Related : http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing?noredirect=1&lq=1 – Suraj Jain Jan 12 '17 at 10:35

2 Answers2

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thanks, although, what's the "untyped parameter of printf" that you're talking about? – nirvanaswap Feb 19 '16 at 02:14
  • @nirvanaswap 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. – Sergey Kalinichenko Feb 19 '16 at 02:16
-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.

ddbug
  • 1,392
  • 1
  • 11
  • 25
  • 1
    I am dereferencing it, so clearly %p isn't what I'm looking for right? – nirvanaswap Feb 19 '16 at 02:10
  • @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. – ddbug Feb 19 '16 at 02:21
  • this is quite wrong. it is always valid to address object memory by `char *`; the most basic memcpy implementations do this. – Hello71 Sep 01 '17 at 12:52
  • 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. – ddbug Sep 01 '17 at 14:42