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.