From: Linus Torvalds <firstname.lastname@example.org>
Subject: Re: Implementation defined behaviour in read_write.c
Date: Wed, 22 Sep 2004 14:43:39 GMT
On Wed, 22 Sep 2004, Rainer Weikusat wrote:
> 220.127.116.11 Signed and unsigned integers
> When a value with integer type is converted to another integer
> type other than _Bool, if the value can be represented by the
> new type, it is unchanged.
> Otherwise, the new type is signed and the value cannot be
> represented in it; either the result is implementation-defined
> or an implementation-defined signal is raised.
> The requirement for implementation defined is that the implementation
> documents the behaviour (which gcc at least up to 3.4.4 doesn't).
They don't, because they do the only thing they _can_ do. Bit-for-bit copy
of a 2's complement value. Anything else would be basically impossible for
an optimizing compiler to do unless it actively _tried_ to screw the user
over. In other words, you're likely to see something else only on a C
simulator interface that does strict conformance testing (as opposed to
test for working).
And you are correct to point out the difference between implementation-
defined and un-defined. Implementation-defined means that it has some
well-defined semantics, and quite frankly, Linux _does_ depend on 2's
complement. I don't expect to ever see anything else (where "ever" is a
long time, although obviously not really "forever"), but if we do, we'll
have to consider that architecture something very special indeed.
> not a problem with the current compiler, but I happen to know by
> coincedence that some people of unknown relations to the gcc team
> (like the person who wrote this advisory:
> would like to turn it into a problem, because they strongly believe it
> is "the right thing to do"
There are tons of people who have theoretical concerns that they try to
push on the real world. Too many of them have talked to the gcc people,
but I think the gcc people are basically sane. So I wouldn't worry _too_
That said, there are other cases where signed integer arithmetic should be
avoided. The signed<->unsigned conversions are safe due to their
implementation-defined behaviour (and only one sane way to do them), but
there _are_ cases like signed integer overflow that really is undefined,
and where a compiler can actually generate code that differs because it
"knows" that signed integers cannot overflow.
However, in this case that is not what is happening in read_write.c. All
the arithmetic is done in proper unsigned types, and only the last check
is done with a (well-defined) signed conversion.
Btw, to see other places where we do depend on this 2's complement
behaviour, just look at "time_before()" and friends.