Structures and casting in C

前端 未结 8 1506
野性不改
野性不改 2020-12-16 02:07

I was wondering:

If I have structure definitions, for example, like this:

struct Base {
  int foo;
};

struct Derived {
  int foo; // int foo is comm         


        
8条回答
  •  别那么骄傲
    2020-12-16 02:53

    Many real-world C programs assume the construct you show is safe, and there is an interpretation of the C standard (specifically, of the "common initial sequence" rule, C99 §6.5.2.3 p5) under which it is conforming. Unfortunately, in the five years since I originally answered this question, all the compilers I can easily get at (viz. GCC and Clang) have converged on a different, narrower interpretation of the common initial sequence rule, under which the construct you show provokes undefined behavior. Concretely, experiment with this program:

    #include 
    #include 
    
    typedef struct A { int x; int y; }          A;
    typedef struct B { int x; int y; float z; } B;
    typedef struct C { A a;          float z; } C;
    
    int testAB(A *a, B *b)
    {
      b->x = 1;
      a->x = 2;
      return b->x;
    }
    
    int testAC(A *a, C *c)
    {
      c->a.x = 1;
      a->x = 2;
      return c->a.x;
    }
    
    int main(void)
    {
      B bee;
      C cee;
      int r;
    
      memset(&bee, 0, sizeof bee);
      memset(&cee, 0, sizeof cee);
    
      r = testAB((A *)&bee, &bee);
      printf("testAB: r=%d bee.x=%d\n", r, bee.x);
    
      r = testAC(&cee.a, &cee);
      printf("testAC: r=%d cee.x=%d\n", r, cee.a.x);
    
      return 0;
    }
    

    When compiling with optimization enabled (and without -fno-strict-aliasing), both GCC and Clang will assume that the two pointer arguments to testAB cannot point to the same object, so I get output like

    testAB: r=1 bee.x=2
    testAC: r=2 cee.x=2
    

    They do not make that assumption for testAC, but — having previously been under the impression that testAB was required to be compiled as if its two arguments could point to the same object — I am no longer confident enough in my own understanding of the standard to say whether or not that is guaranteed to keep working.

提交回复
热议问题