Unhappy lack of warning..
Linus Torvalds
torvalds@transmeta.com
Sun Feb 13 23:55:00 GMT 2000
Hi,
I was just made aware of a surprising (and extremely stupid) bug in the
Linux PCMCIA layer that actually got introduced as part of a cleanup
effort to avoid type warnings and make sure the compiler warn us if we'd
pass around pointers of the wrong types..
The PCMCIA laye used to have (and still has, for compatibility old
drivers) an interface with anonymous pointers, often used as in-out
arguments, where you pass it basically a ioctl()-like pointer that is used
for input, and often the return value is passed back in the same space.
I hated it, because it means the compiler can never check the argument
types. So we cleaned it up, and separated out the anonymous pointer
interface into separate functions with well-defined arguments and proper
type-checking. Good so far, as a few non-serious type problems were
actually found this way.
Now, the old anonymous pointer interface was still supported, and had code
something like this:
case OpenMemory:
{
memory_handle_t m;
int ret = pcmcia_open_memory(a1, a2, &m);
*(memory_handle_t *)a1 = m;
return ret;
}
where "pcmcia_open_memory()" is the new proper type-checking thing.
Everybody is happy - old drivers work, and new drivers won't have the
horrible casting thing with anonymous pointers and no type-checking.
Or everybody _WOULD_ have been happy, if it wasn't for the fact that our
re-written compatibility layer had a typo - a forgotten "*". So it had
(memory_handle_t *)a1 = m;
instead of
*(memory_handle_t *)a1 = m;
which makes absolutely no sense at all. It shouldn't even have passed
through the compiler, except for the gcc "casting an lvalue" extension.
And in fact, the lvalue cast extension acts in such a way that it not only
makesit legal gnu-C, it also makes a non-sensical assignment with
completely different types pass silently through the compiler with no
warning.
Anyway, that particular Linux bug is obviously fixed now, and I just
wanted to ask a quick question about this - not a very pressing issue, but
maybe something to give a fleeting thought..
Is there any way to disable this particular gcc extension? I've found it
useful in some cases (eg "(char *)ptr += 5;" in order to avoid a mess of
other casts when you really want to treat "ptr" as a byte pointer for a
very specific purpose), but it obviously had ramifications that I have
to say that I don't particularly enjoy ;)
(Yes, I can make it warn using "-pedantic", but that will warn about other
things that are truly useful like "long long" and variable-argument macros
etc that don't have these kinds of strange side-effects).
Thanks,
Linus
More information about the Gcc-bugs
mailing list