Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is casting a pointer to different structs guaranteed to be meaningful in C89?

Tags:

c

struct

c89

I have two structs like

struct X {
  int x;
  double *y;
};

struct Y {
  int a;
  double *b;
  char c;
};

Is casting a pointer to struct Y to a pointer to struct X guaranteed to behave consistently in a reasonable manner (i.e. x->x and x->y correspond to y->a and y->b respectively) by the C89 standard? Less important, but would be really cool if you also happen to know, does this hold true for later standards as well (e.g. C11) and other languages that have significant syntactic and semantic overlap with C (e.g. C++XX, Objective-C)?

like image 590
math4tots Avatar asked Oct 26 '15 19:10

math4tots


1 Answers

It's undefined behavior. Python relied on this before and had to fix that. If you have struct Y include struct X as its first element, you can use that for a similar effect:

struct Y {
    struct X a;
    char c;
};

struct Y y;
struct X *x = (struct X *) &y; /* legal! */

There's also a special case for unions:

struct X {
  int x;
  double *y;
};

struct Y {
  int a;
  double *b;
  char c;
};

union XY {
    struct X x;
    struct Y y;
};

union XY xy;
xy.x.x = 0;
printf("%d\n", xy.y.a); /* legal! */

In later versions of the C standard, the compiler is only required to handle X and Y objects aliasing each other if a union definition like this is actually in scope, but in C89, it mostly has to assume such a definition exists somewhere. That still doesn't make it safe to cast a struct Y * to a struct X *, though; if the compiler knows that a specific struct Y is not part of a union, it may still assume that a struct X * can't possibly alias it.

like image 185
user2357112 supports Monica Avatar answered Nov 16 '22 01:11

user2357112 supports Monica