2
struct test
{
    char member1;
    char member2;
};

int main(void)
{
    struct test structure[] = {'h', 'i'};
    static void* p = &structure;

    printf("%i", *((int*)p));

    return 0;
}

We all know that structure should point to the address of the first element in the struct. Why by dereferencing it like that, it returns the address itself instead?

M.M
  • 138,810
  • 21
  • 208
  • 365
Corelation
  • 79
  • 7
  • 1
    An `int` is not a `char`. Pointers to those are not interchangeable. – n. m. could be an AI Nov 03 '14 at 04:50
  • 1
    What are you using to compile this? clang and gcc should both fail by default on this code, even with the missing `;` fixed. – Iskar Jarak Nov 03 '14 at 04:57
  • I think this is just a duplicate: http://stackoverflow.com/questions/2528318/how-come-an-arrays-address-is-equal-to-its-value-in-c – Bill Lynch Nov 03 '14 at 05:01
  • @BillLynch I agree that he is misunderstanding that `(int *)structure == (int *)&structure` here although there is a bot more going on – M.M Nov 03 '14 at 06:01

3 Answers3

5

Your code exhibits an undefined behaviour.

You are casting a structure * to type int * and dereferencing. When (mostly) the size of int is more, you are accessing offbound memory. (This is one reason, there are a few more)

+---+---+---+---+
| h | i | ? | ? |
+---+---+---+---+
Print as int: ? ? i h if machine is little endian

In ascii coding
+---+---+---+---+
| 68| 69| ? | ? |
+---+---+---+---+
Print as int: ?? ?? 69 68

Live code here

Correct usage of structures is:

struct test s1   = {'h', 'i'};
struct test s2[] = { {'t', 'o'}, {'d', 'o'} };

printf("s1   : %c, %c\n", s1.member1, s1.member2);
printf("s2[0]: %c, %c\n", s2[0].member1, s2[0].member2);
printf("s2[1]: %c, %c\n", s2[1].member1, s2[1].member2);
Gyapti Jain
  • 4,056
  • 20
  • 40
1

This causes undefined behaviour due to violation of the strict aliasing rule.

When reading via the expression *(int *)some_pointer , it is only valid in the following cases:

  • some_pointer points to an object declared with type int or unsigned int (optionally with const or volatile qualifiers).
  • some_pointer points into dynamically-allocated storage that has previously had an int or unsigned int written to exactly that location.

Some compilers may optimize according to this rule. For more information about the benefits of this, see here

Even if your char array had at least sizeof(int) bytes in it, the compiler might still ignore (or worse!) your attempt to alias those as an int. Despite this fact it's not uncommon in "real" code for people to try this, which is why a lot of existing code has to be compiled with -fno-strict-aliasing.

NB. There may also be undefined behaviour if structure is not correctly aligned for int.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • I am trying to reinvent `fread` and make it to do the same thing but from another instance instead of file stream. – Corelation Nov 03 '14 at 06:02
0

Here you have an array called structure. Its name gives the address. So you don't need to have & operator before it.

You can have either p = &structure[0]; or p = structure;

Ginu Jacob
  • 1,588
  • 2
  • 19
  • 35