[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0702131212120.3604@woody.linux-foundation.org>
Date: Tue, 13 Feb 2007 12:24:09 -0800 (PST)
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Sergei Organov <osv@...ad.com>
cc: J.A. MagallÃÃÃón
<jamagallon@....com>, Jan Engelhardt <jengelh@...ux01.gwdg.de>,
Jeff Garzik <jeff@...zik.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: Re: somebody dropped a (warning) bomb
On Tue, 13 Feb 2007, Sergei Organov wrote:
> > Exactly because "char" *by*definition* is "indeterminate sign" as far as
> > something like "strlen()" is concerned.
>
> Thanks, I now understand that you either don't see the difference
> between "indeterminate" and "implementation-defined" in this context or
> consider it non-essential, so I think I've got your point.
The thing is, "implementation-defined" does actually matter when you can
_depend_ on it.
For example, there's a *huge* difference between "undefined" and
"implementation-defined". A program can actually depend on something like
char c = 0x80;
if (c < 0)
..
always having the *same* behaviour for a particular compiler (with a
particular set of compile flags - some compilers have flags to change the
sign behaviour).
So yes, there "implementation defined" actually has a real and worthwhile
meaning. It is guaranteed to have _some_ semantics within the confines of
that program, and they are defined to be consistent (again, within the
confines of that particular program).
So I agree that "implementation defined" doesn't always mean
"meaningless".
BUT (and this is a big but) within the discussion of "strlen()", that is
no longer true. "strlen()" exists _outside_ of a single particular
implementation. As such, "implementation-defined" is no longer something
that "strlen()" can depend on.
As an example of this argument, try this:
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv)
{
char a1[] = { -1, 0 }, a2[] = { 1, 0 };
printf("%d %d\n", a1[0] < a2[0], strcmp(a1, a2) < 0);
return 0;
}
and *before* you compile it, try to guess what the output is.
And when that confuses you, try to compile it using gcc with the
"-funsigned-char" flag (or "-fsigned-char" if you started out on an
architecture where char was unsigned by default)
And when you really *really* think about it afterwards, I think you'll go
"Ahh.. Linus is right". It's more than "implementation-defined": it really
is totally indeterminate for code like this.
(Yeah, the above isn't "strlen()", but it's an even subtler issue with
EXACTLY THE SAME PROBLEM! And one where you can actually see the _effects_
of it)
Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists