Strict aliasing and overlay inheritance

前端 未结 2 1108
攒了一身酷
攒了一身酷 2020-12-17 21:59

Consider this code example:

#include 

typedef struct A A;

struct A {
   int x;
   int y;
};

typedef struct B B;

struct B {
   int x;
   in         


        
2条回答
  •  感情败类
    2020-12-17 22:11

    The line with *ap = is a strict aliasing violation: an object of type B is written using an lvalue expression of type A.

    Supposing that line was not present, and we moved onto ap->x = 10; ap->y = 20;. In this case an lvalue of type int is used to write objects of type int.

    There is disagreement about whether this is a strict aliasing violation or not. I think that the letter of the Standard says that it is not, but others (including gcc and clang developers) consider ap->x as implying that *ap was accessed. Most agree that the standard's definition of strict aliasing is too vague and needs improvement.

    Sample code using your struct definitions:

    void f(A* ap, B* bp)
    {
      ap->x = 213;
      ++bp->x;
      ap->x = 213;
      ++bp->x;
    }
    
    int main()
    {
       B b = { 0 };
       f( (A *)&b, &b );
       printf("%d\n", b.x);
    }
    

    For me this outputs 214 at -O2, and 2 at -O3 , with gcc. The generated assembly on godbolt for gcc 6.3 was:

    f:
        movl    (%rsi), %eax
        movl    $213, (%rdi)
        addl    $2, %eax
        movl    %eax, (%rsi)
        ret
    

    which shows that the compiler has rearranged the function to:

    int temp = bp->x + 2;
    ap->x = 213;
    bp->x = temp;
    

    and therefore the compiler must be considering that ap->x may not alias bp->x.

提交回复
热议问题