tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: in which we present an ugly hack to make sys/queue.h CIRCLEQ work



On Thu, Nov 21, 2013 at 11:02:24PM -0500, Ken Hornstein wrote:
 > >Modulo some administrative details, it's just "no object in memory may
 > >be accessed using more than one type".
 > 
 > Ok ... I _think_ I see it.  But doesn't that mean that like 90% of the casts
 > used by C programmers are totally wrong? :-)

Yes. That's why -fno-strict-aliasing is very popular, and would be
more popular if people in general were more aware of the issue.

As noted, inspecting the representation of an object using char * or
unsigned char * is explicitly allowed. And some constructions with
unions are allowed. But other stuff isn't.

Note that the bog-standard (struct sockaddr *) cast that one needs and
conventionally uses to call bind(2), connect(2), accept(2), and
similar is, strictly speaking, illegal.

 > Alright, I think I understand.  If tqe_prev pointed to a queue entry
 > that would be the problem, because that memory already has a TAILQ_ENTRY
 > type.

Yes. The idea in C is that when you first access fresh memory, that
imprints it with a type. You're then supposed to use only the same
type to access it again later, until you free() it.

 > So ... looking at this code ... it seems like the core problem is that
 > TAILQ_HEAD and TAILQ_ENTRY are two different types (even though they
 > literally the same structure layout).  So if TAILQ_HEAD and TAILQ_ENTRY
 > were the same structure, it wouldn't be an issue.  It doesn't quite leap
 > out to me how that would be possible without changing the API a bit.

I think it can be done by sticking an anonymous union into TAILQ_HEAD,
but of course anonymous unions aren't supported until C11.

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index