Sujet : Re: Cray style vectors
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.archDate : 12. Mar 2024, 19:51:21
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <86frwvqo5y.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Thomas Koenig <
tkoenig@netcologne.de> writes:
On 2024-02-25, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
Thomas Koenig <tkoenig@netcologne.de> writes:
>
Tim Rentsch <tr.17687@z991.linuxsc.com> schrieb:
>
Thomas Koenig <tkoenig@netcologne.de> writes:
>
Signed integer overflow is undefined behavior in C and prohibited
in Fortran. Yet, there is no straightforward, standard-compliant
way to check for signed overflow (and handle this appropriately)
in either language. [...]
>
It isn't hard to write standard C code to determine whether a
proposed addition or subtraction would overflow, and does so
safely and reliably.
>
Also efficiently and without resorting to implementation-
defined or undefined behavior (and without needing a bigger
type)?
>
[...]
>
Heavens to Betsy! Are you impugning the quality and excellence
of my code? Of *my* code? I can only hope that you are suitably
chagrined and contrite. ;)
>
It's a little bit tedious perhaps but not
difficult. Checking code can be wrapped in an inline function
and invoke whatever handling is desired, within reason.
>
Maybe you could share such code?
>
Rather that do that I will explain.
>
An addition overflows if the two operands have the same sign and
the sign of an operand is the opposite of the sign of the sum
(taken mod the width of the operands). Convert the signed
operands to their unsigned counterparts, and form the sum of the
unsigned values. The sign is just the high-order bit in each
case. Thus the overflow condition can be detected with a few
bitwise xors and ands.
>
Subtraction is similar except now overflow can occur only when
the operands have different signs and the sign of the sum is
the opposite of the sign of the first operand.
>
The above description works for two's complement hardware where
unsigned types have the same width as their corresponding signed
types. I think for most people that's all they need. The three
other possibilities are all doable with minor adjustments, and
code appropriate to each particular implementation can be
selected using C preprocessor conditional, as for example
>
...
>
but that's implementation-defined behavior, correct?
There is implementation-dependent behavior but there isn't any
implementation-defined behavior. The result has to depend on the
implementation because different implementations can imply
different results, as for example whether the representation for
signed integers uses two's complement or ones' complement.
Roughly speaking the distinction is whether code is relying on an
implementation choice other than the choice assumed. There is
nothing wrong, for example, with code that holds the value of the
character constant 'a' in a variable, as long as the code makes
sure that there are no wrong assumptions about what specific
value that is (as for example the wrong assumption that the
expression c + "A" - "a" can be used to change a letter from
lower case to upper case). The C standard doesn't clearly
differentiate behavior /of the implementation/ and behavior /of
the program/. I took your question to mean, Does the code resort
to implementation-defined behavior so as to rely on an unreliable
assumption, ie, the kind that can go wrong if a different
implementation-defined choice is made? The answer is that the
code does not rely on any such assumption. So strictly speaking
the code does /involve/ implementation-defined choices (as indeed
essentially all programs do). But it does not /depend/ on
implementation-defined choices in any way that risks changing the
correctness of its results.