Violating of strict-aliasing in C, even without any casting?

前端 未结 7 762
情深已故
情深已故 2021-01-31 07:02

How can *i and u.i print different numbers in this code, even though i is defined as int *i = &u.i;? I can only assuming

相关标签:
7条回答
  • 2021-01-31 08:03

    Looks like this is a result of the optimizer doing its magic.

    With -O0, both lines print 100 as expected (assuming little-endian). With -O2, there is some reordering going on.

    gdb gives the following output:

    (gdb) start
    Temporary breakpoint 1 at 0x4004a0: file /tmp/x1.c, line 14.
    Starting program: /tmp/x1
    warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000
    
    Temporary breakpoint 1, main () at /tmp/x1.c:14
    14      {
    (gdb) step
    15          *i  = 2;
    (gdb)
    18          printf(" *i = %d\n",  *i); // prints 2
    (gdb)
    15          *i  = 2;
    (gdb)
    16          *s  = 100;
    (gdb)
    18          printf(" *i = %d\n",  *i); // prints 2
    (gdb)
     *i = 2
    19          printf("u.i = %d\n", u.i); // prints 100
    (gdb)
    u.i = 100
    22      }
    (gdb)
    0x0000003fa441d9f4 in __libc_start_main () from /lib64/libc.so.6
    (gdb)
    

    The reason this happens, as others have stated, is because it is undefined behavior to access a variable of one type through a pointer to another type even if the variable in question is part of a union. So the optimizer is free to do as it wishes in this case.

    The variable of the other type can only be read directly via a union which guarantees well defined behavior.

    What's curious is that even with -Wstrict-aliasing=2, gcc (as of 4.8.4) doesn't complain about this code.

    0 讨论(0)
提交回复
热议问题