On May 15, 2006, at 8:56 AM, Igor Bukanov wrote:
Consider the following code that starting with GCC 4.1.0 generates
'dereferencing type-punned pointer will break strict-aliasing rules'
warning:

Yup. Kinda does seem a flaw in the C language. You could switch to C ++. :-)

~> cat test.c
struct inner {
   struct inner *next;
};

struct outer {
   struct inner base;
   int value;
};

/* List of outer elements where all outer.base.next point to struct outer */
struct outer_list {
   struct outer *head;
};

struct outer *search_list(struct outer_list *list, int value)
{
   struct outer *elem, **pelem;

Instead, try struct inner **pelem;,


   pelem = &list->head;

Instead try:

  struct inner_list ilist_node;
  struct inner_list *ilist = &ilist_node;
  ilist->head = list->head;
  pelem = &ilist->head;

and keep all the types as **inner.  At the end, you can then

  list->head = ilist->head;

But why the warning is generated?

The two I don't think are compatible types. An example of this might be:

       [#5] EXAMPLE 2 After the declarations

               typedef struct s1 { int x; } t1, *tp1;
               typedef struct s2 { int x; } t2, *tp2;

       type t1 and the type pointed to by tp1 are compatible.  Type
       t1  is  also  compatible  with  type  struct  s1,  but   not
       compatible with the types struct s2, t2, the type pointed to
       by tp2, or int.                                              |

Doesn't it guaranteed that offsetof(struct outer, base) == 0 and one can always safely cast struct inner* to struct outer* if struct inner is a part struct outer so struct* outer can alias struct* inner?

Yes, but this isn't used to decide the aliasing of two pointers.

Reply via email to