Subject: Re: Documentation of abs(3), div(3) etc.
To: Martijn van Buul <pino+gmane_os_netbsd_devel_general@dohd.org>
From: Krister Walfridsson <cato@df.lth.se>
List: tech-misc
Date: 02/11/2007 04:52:11
On Sat, 10 Feb 2007, Martijn van Buul wrote:
> Not sure if this is a real improvement, and it *certainly* doesn't
> make things work all of a sudden. There is one thing the implementation-
> defined behaviour cannot do: Suddenly make -INT_MIN fito a signed int.
Please re-read the whole of my previous mail closely. The point is to
disprove your statement:
> My point was that the proposed change indicates is pointless, doesn't
> change a single opcode, and obviously indicates a lack of understanding.
by showing that abs(INT_MIN) is undefined in our current implementation,
but that it becomes defined (i.e. as abs(INT_MIN) == INT_MIN) by the
proposed change.
(But I want to point out that it would be silly change the implementation
to make abs(INT_MIN) defined. It is much better to just say that the
value is undefined as Christian Biere proposed.)
> In all likelyness, the result will be the same: After
>
> signed int foo = abs(INT_MIN);
>
> foo will probably end up containing an unchanged INT_MIN - which is
> what the manpage is hinting at :)
Kind of. If you directly do a "printf("%d\n", foo);", it will
probably print the value of INT_MIN. But let us look at a slightly
more interesting example.
Consider the following code containing the two implementations of abs:
#include <stdio.h>
static int abs1(int a)
{
return a < 0 ? -a : a;
}
static int abs2(int a)
{
return a < 0 ? -(unsigned)a : a;
}
void bar(int a)
{
int foo;
foo = abs1(a);
if (foo < 0)
printf("abs1(%d) < 0\n", a);
foo = abs2(a);
if (foo < 0)
printf("abs2(%d) < 0\n", a);
}
and we call the function foo() from an other file:
#include <limits.h>
int main(void)
{
bar(INT_MIN);
return 0;
}
Compiling this with a current gcc such as
gcc version 4.3.0 20070106 (experimental)
gives the result
> ./a.out
abs2(-2147483648) < 0
i.e. gcc manages to eliminate the first if-statement because it knows that
"if (abs1(a) < 0)" always is false (or undefined. But it do not need to
care about undefined values as no valid C program may invoke undefined
behavior). But the result of foo2(a) is defined for all possible values
of a, and thus gives the expected result.
/Krister