This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: INT_MIN % -1
- From: Robert Dewar <dewar at gnat dot com>
- To: Paul Schlie <schlie at comcast dot net>
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 29 Nov 2004 23:36:24 -0500
- Subject: Re: INT_MIN % -1
- References: <BDD14F36.8169%schlie@comcast.net>
Paul Schlie wrote:
(where I'm assuming: (-INT_MIN / -1) => -1 isn't reasonably correct or
necessary, nor is a run-time exception/trap)
Although possibly naive, I'd like to think that the C standard won't be used
as a crutch, but that GCC may rise above many of the unspecified behaviors,
and establish instead, well defined logically consistent useful ones, which
others may aspire to emulate.
One possibility would be to have an optional divide by zero trap that sets
the right result and continues. Then there is a special compiler switch
that sets up this trap routine if you really really really want this not
very useful marginal behavior (a real division by zero is undefined, so
it is fine to do anything you like). That being said, GNAT (the Ada front
end) does go to the trouble of doing this right. Given the source program:
procedure K is
X, Y : Integer;
function Id (X : Integer) return Integer is begin return X; end Id;
begin
X := Id (Integer'First);
Y := Id ( - 1);
X := X mod y;
end;
(the Id function is to stop the compiler from doing optimizing value tracing :-)
The generated code (-gnatG output) (with checks off to simplifty) looks like:
procedure k is
x : integer;
y : integer;
function k__id (x : integer) return integer is
begin
return x;
end k__id;
begin
x := k__id (-16#8000_0000#);
y := k__id (-1);
x := (if y = -1 then 0 else x mod y);
return;
end k;
The test for y = -1 is precisely to handle this case, and it is only one test.
Note that the cost in Ada is generally smaller than in C, because we know more
about the range of variables. For example, the Ada program:
procedure K is
X, Y : Integer range -1000 .. +1000;
function Id (X : Integer) return Integer is begin return X; end Id;
begin
X := Id (1);
Y := Id ( - 1);
X := X mod y;
end;
Does not generate the check for -1, because it knows that X cannot be Integer'First.