https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61421
--- Comment #18 from mimamer at gmail dot com --- Ah? I didn't figure that was allowed per strict aliasing rules. But it still doesn't solve one problem: inline T *dequeue() { node *head = anchor.next; anchor.next = head->next; head->next->prev = &anchor; return (T *)head; }; The last typecast is invalid when the list is empty and thus returns the anchor, a special element that so far I checked with equality to list2::end(): inline T* end() const { return (T *)&anchor; } But it is a huge step forward as checking for an empty list in dequeue() is just ok so as to return NULL instead of the anchor.