-2
#include <stdio.h>

int main(){
  int arr[3] = {2, 3, 4};
  char *p;

  p = arr;
  p = (char*)((int*)(p));
  
  printf("%d, ", *p);
  p = (int*)(p+1);
  printf("%d", *p);
  return 0;
}

Why is the output of the following C program 2, 0 and not 0, 0? Does it have something to do with the endianness of the bytes of ints?

Lundin
  • 195,001
  • 40
  • 254
  • 396
Serket
  • 3,785
  • 3
  • 14
  • 45
  • 1
    `p = (int*)(p+1);` this violates strict aliasing rule and invokes UB. It makes the resulting pointer unaligned. There are lots of duplicates on SO – phuclv Feb 23 '23 at 09:59
  • @phuclv No it's just invalid C. – Lundin Feb 23 '23 at 10:00
  • @Lundin the code compiles and works so... – Serket Feb 23 '23 at 10:00
  • 1
    @Serket No it does not compile _cleanly_. [What must a C compiler do when it finds an error?](https://software.codidact.com/posts/277340) – Lundin Feb 23 '23 at 10:03
  • Being able to make your compiler create a binary is not the same as having valid correct code. – Gerhardh Feb 23 '23 at 10:04
  • @Lundin this is a question from my university exam, this is not my code. the question asks what the output is. My job is not to make sure the code compiles cleanly. – Serket Feb 23 '23 at 10:05
  • @i486 this is a test on pointers – Serket Feb 23 '23 at 10:06
  • @Serket Okay please pass on my link regarding how beginners should configure their compiler to your teacher. In case you wish to teach your teacher why the code is wrong, also pass on ["Pointer from integer/integer from pointer without a cast" issues](https://stackoverflow.com/questions/52186834/pointer-from-integer-integer-from-pointer-without-a-cast-issues) In addition 6.5.4 regarding the cast operator: "Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast." – Lundin Feb 23 '23 at 10:19
  • It's really depressive how many bad C teachers there are out there. What's the requirement for teaching C at university these days? "CV: Took a youtube tutorial"? – Lundin Feb 23 '23 at 10:24

1 Answers1

2

The code is mostly invalid C all over the place. Do yourself a favour and stop chasing bugs that the compiler has already found, as well as stop examining the output of "not C" undefined behavior programs, by configuring your compiler as a conforming C compiler instead: What compiler options are recommended for beginners learning C?

  • p = arr; This is invalid C. Anything can happen.
  • p = (char*)((int*)(p)); This line achieves absolutely nothing.
  • p = (int*)(p+1); This is invalid C. Anything can happen.

If we fix the problem in your program as

#include <stdio.h>

int main(){
  int arr[3] = {2, 3, 4};
  char *p;
  p = (char*)arr;
  printf("%d, ", *p);
  p++;
  printf("%d", *p);
  return 0;
}

We do get the output 2, 0 on an little endian machine. On a 32 bit little endian machine, int arr[3] = {2, 3, 4}; is stored in memory as (lowest to highest address):

02 00 00 00 03 00 00 00 04 00 00 00

So if you examine the array byte by byte, that's what you'll get. For more info see What is CPU endianness?

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Cheeky bonus challenge about little endianess: explain how this conforming C program prints "hello world": https://godbolt.org/z/TG7P416f1 :) – Lundin Feb 23 '23 at 10:17