This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: INT_MIN % -1


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]