L
Lawrence Kirby
On Mon, 20 Dec 2004 12:30:01 +0100, Charlie Gordon wrote:
....
I accept that I am only going on personal experience for the "well known"
bit and that may not be representative. If it isn't that is a pity. As for
your claim of non-portability it is just plain wrong, both in terms of
what the standard requires and, again in my experience, the lack of real C
compilers that are broken in this respect.
There is no integer overflow here. The rules for conversion from
any integer type to an unsigned integer type define clearly what happens
when the value being converted is not in the range of values representable
by the target type. It is never undefined.
It is easy to show from the rules in the standard that it must be.
Representation is irrelevant, the results of casts are defined in terms of
values NOT representations. If the result has a different bit pattern,
e.g. on a 1's complement architecture, the compiler must generate code
that makes the appropriate changes.
Your case is based on incorrect assumptions. The C99 Standard says:
"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, if the new type is unsigned, the value is converted by
repeatedly adding or subtracting one more than the maximum value that can
be represented in the new type until the value is in the range of the new
type."
So if we convert the *value* -1 to an unsigned type the value isn't
representable directly in the new type so we apply the 2nd paragraph to
find out what to do. We can add one more than the maximum value that can
be represented by the unsigned type i.e. mathematically
-1 + (MAX_VALUE_OF_NEW_TYPE+1), which reduces to MAX_VALUE_OF_NEW_TYPE.
This is in the range of the new type so we are finished, bar noting that
size_t is defined as an unsigned integer type so this analysis applies to
the for() loop above.
The C90 wording is different but the result is the same.
Lawrence
....
Not at all !
It is not well known, and it is not portable.
I accept that I am only going on personal experience for the "well known"
bit and that may not be representative. If it isn't that is a pity. As for
your claim of non-portability it is just plain wrong, both in terms of
what the standard requires and, again in my experience, the lack of real C
compilers that are broken in this respect.
Furthermore, it is not reliable : it is blatant undefined behaviour (because of
integer overflow).
There is no integer overflow here. The rules for conversion from
any integer type to an unsigned integer type define clearly what happens
when the value being converted is not in the range of values representable
by the target type. It is never undefined.
(size_t)-1 is not necessarily the largest value size_t can represent :
It is easy to show from the rules in the standard that it must be.
just
think of the different representations C99 allows for integer arithmetic. It
may work for 2's complement, doesn't work for 1's complement (off by one), and
completely wrong for sign/magnitude.
Representation is irrelevant, the results of casts are defined in terms of
values NOT representations. If the result has a different bit pattern,
e.g. on a 1's complement architecture, the compiler must generate code
that makes the appropriate changes.
This loop is horrible, it should be banned. I rest my case.
Your case is based on incorrect assumptions. The C99 Standard says:
"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, if the new type is unsigned, the value is converted by
repeatedly adding or subtracting one more than the maximum value that can
be represented in the new type until the value is in the range of the new
type."
So if we convert the *value* -1 to an unsigned type the value isn't
representable directly in the new type so we apply the 2nd paragraph to
find out what to do. We can add one more than the maximum value that can
be represented by the unsigned type i.e. mathematically
-1 + (MAX_VALUE_OF_NEW_TYPE+1), which reduces to MAX_VALUE_OF_NEW_TYPE.
This is in the range of the new type so we are finished, bar noting that
size_t is defined as an unsigned integer type so this analysis applies to
the for() loop above.
The C90 wording is different but the result is the same.
Lawrence