* Division by zero @ 2005-06-11 21:03 Lurker 2005-06-12 2:00 ` David C. Hoos, Sr. ` (2 more replies) 0 siblings, 3 replies; 41+ messages in thread From: Lurker @ 2005-06-11 21:03 UTC (permalink / raw) Hi, I'm curios about the problem which I discovered by accident. The code below is of course very much reduced to show the it: function x(a: integer) return integer is some_constant: constant := 0; begin -- return 1/some_constant; -- line 1 -- return a/some_constant; -- line 2 end; If line 1 is uncommented compiler (Gnat 3.15 for Widows) produces the expected error about division by zero. If line 2 is uncommented it passes compilation with no problem. Surely that's not right? Or did I miss something? ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-11 21:03 Division by zero Lurker @ 2005-06-12 2:00 ` David C. Hoos, Sr. 2005-06-12 3:04 ` Lurker 2005-06-12 12:21 ` Robert A Duff 2005-06-12 22:53 ` Georg Bauhaus 2 siblings, 1 reply; 41+ messages in thread From: David C. Hoos, Sr. @ 2005-06-12 2:00 UTC (permalink / raw) To: Lurker; +Cc: comp.lang.ada The reason for the difference is that because both terms of line 1 are known at compile time, the computation is performed at compile time, and thus raises the exception. Since the numerator of line 2 is a variable, the compiler does not attempt any computation, and thus does not signal an error. Constraint_Error will be raised at runtime. ----- Original Message ----- From: "Lurker" <nowhere@nothing.com> Newsgroups: comp.lang.ada To: <comp.lang.ada@ada-france.org> Sent: June 11, 2005 4:03 PM Subject: Division by zero > Hi, > > I'm curios about the problem which I discovered by accident. > The code below is of course very much reduced to show > the it: > > function x(a: integer) return integer is > > some_constant: constant := 0; > > begin > > -- return 1/some_constant; -- line 1 > > -- return a/some_constant; -- line 2 > > end; > > > > If line 1 is uncommented compiler (Gnat 3.15 for Widows) > > produces the expected error about division by zero. > > If line 2 is uncommented it passes compilation with no problem. > > Surely that's not right? Or did I miss something? > > > > > _______________________________________________ > comp.lang.ada mailing list > comp.lang.ada@ada-france.org > http://www.ada-france.org/mailman/listinfo/comp.lang.ada > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 2:00 ` David C. Hoos, Sr. @ 2005-06-12 3:04 ` Lurker 2005-06-12 8:39 ` Dmitry A. Kazakov [not found] ` <5sana1pm436l6vboifijqblu0irf84afkr@4ax.com> 0 siblings, 2 replies; 41+ messages in thread From: Lurker @ 2005-06-12 3:04 UTC (permalink / raw) "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com> wrote in message news:mailman.16.1118541539.17633.comp.lang.ada@ada-france.org... > The reason for the difference is that because both terms of line 1 > are known at compile time, the computation is performed at compile > time, and thus raises the exception. > > Since the numerator of line 2 is a variable, the compiler does not > attempt any computation, and thus does not signal an error. Well, yes. But can't it tell that division by zero is always wrong regardless? What has actually happened (outside that toy example) was that there was a constant declared in one place and used in many others. Someone went ahead and changed it (for a good reason) to zero. However, one of the uses of that constant was to divide by it. > > Constraint_Error will be raised at runtime. It was. My question was - should it have been caught at compile time instead? > > ----- Original Message ----- > From: "Lurker" <nowhere@nothing.com> > Newsgroups: comp.lang.ada > To: <comp.lang.ada@ada-france.org> > Sent: June 11, 2005 4:03 PM > Subject: Division by zero > > > > Hi, > > > > I'm curios about the problem which I discovered by accident. > > The code below is of course very much reduced to show > > the it: > > > > function x(a: integer) return integer is > > > > some_constant: constant := 0; > > > > begin > > > > -- return 1/some_constant; -- line 1 > > > > -- return a/some_constant; -- line 2 > > > > end; > > > > > > > > If line 1 is uncommented compiler (Gnat 3.15 for Widows) > > > > produces the expected error about division by zero. > > > > If line 2 is uncommented it passes compilation with no problem. > > > > Surely that's not right? Or did I miss something? > > > > > > > > > > _______________________________________________ > > comp.lang.ada mailing list > > comp.lang.ada@ada-france.org > > http://www.ada-france.org/mailman/listinfo/comp.lang.ada > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 3:04 ` Lurker @ 2005-06-12 8:39 ` Dmitry A. Kazakov 2005-06-12 9:43 ` Lurker 2005-06-12 13:10 ` Robert A Duff [not found] ` <5sana1pm436l6vboifijqblu0irf84afkr@4ax.com> 1 sibling, 2 replies; 41+ messages in thread From: Dmitry A. Kazakov @ 2005-06-12 8:39 UTC (permalink / raw) On Sun, 12 Jun 2005 15:04:17 +1200, Lurker wrote: > "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com> wrote in message > news:mailman.16.1118541539.17633.comp.lang.ada@ada-france.org... >> The reason for the difference is that because both terms of line 1 >> are known at compile time, the computation is performed at compile >> time, and thus raises the exception. >> >> Since the numerator of line 2 is a variable, the compiler does not >> attempt any computation, and thus does not signal an error. > > Well, yes. But can't it tell that division by zero is always wrong > regardless? No, it is not, because it has a defined effect: Constraint_Error. Formally speaking division by zero is not a contract violation and thus cannot be "wrong". Consider the following: A : constant Integer := 0; B : Integer := 1; begin B := B / A; Put_Line ("Hello!"); exception when others => Put_Line ("Good bye!"); The above is a valid program, which should print "Good bye!". At the same time the following is *wrong*: A : constant Integer := 0; B : constant Integer := 1; C : Integer; begin C := B / A; B/A is a static expression, which has to have a value at compile-time. The difference is not in what the compiler might know, but in what it must know. > What has actually happened (outside that toy example) > was that there was a constant declared in one place and used in > many others. Someone went ahead and changed it (for a good > reason) to zero. However, one of the uses of that constant was > to divide by it. > >> Constraint_Error will be raised at runtime. > > It was. My question was - should it have been caught > at compile time instead? I don't think it should. A class of errors which cannot be detected at compile time cannot be compile-time errors. Or, in other words, if you cannot rely on the compiler, you should not pretend you can. (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 8:39 ` Dmitry A. Kazakov @ 2005-06-12 9:43 ` Lurker 2005-06-12 10:36 ` Marius Amado Alves ` (2 more replies) 2005-06-12 13:10 ` Robert A Duff 1 sibling, 3 replies; 41+ messages in thread From: Lurker @ 2005-06-12 9:43 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:79ahr0jozmqb$.10jzllrcjpmsv.dlg@40tude.net... > > Well, yes. But can't it tell that division by zero is always wrong > > regardless? > > No, it is not, because it has a defined effect: Constraint_Error. Formally > speaking division by zero is not a contract violation and thus cannot be > "wrong". Consider the following: > > A : constant Integer := 0; > B : Integer := 1; > begin > B := B / A; > Put_Line ("Hello!"); > exception > when others => > Put_Line ("Good bye!"); > > The above is a valid program, which should print "Good bye!". At the same > time the following is *wrong*: > > A : constant Integer := 0; > B : constant Integer := 1; > C : Integer; > begin > C := B / A; > > B/A is a static expression, which has to have a value at compile-time. OK, I see you point. But, pratically speaking, the chances are that that construct was an error. Perhaps a warning or some such would be enough. If whoever wrote that was sure that's what they meant - fine. But I was always under the impression that the Ada philosophy was to avoid accidental mistakes as much as possible. And division by zero sure should qualify as a suspect at least - not something that just happily gets compiled. > >> Constraint_Error will be raised at runtime. > > > > It was. My question was - should it have been caught > > at compile time instead? > > I don't think it should. A class of errors which cannot be detected at > compile time cannot be compile-time errors. Or, in other words, if you > cannot rely on the compiler, you should not pretend you can. (:-)) I'm afraid I don't follow your logic there. Do you really mean that a constant declared as = 0 cannot be detected at compile time? Yes, the effects of using it to divide something may or may not be ok. But that would equally apply to dividing a literal 1 by it, wouldn't it? (Again, I realise your point about static vs other expressions. But c'mon, unless someone specifically allows and handles cases like that, surely the safest bet would be to at least point out that there is something fishy going on and a "moral equivalent" of asking "are you sure"? > > -- > Regards, > Dmitry A. Kazakov > http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 9:43 ` Lurker @ 2005-06-12 10:36 ` Marius Amado Alves 2005-06-12 11:53 ` Dmitry A. Kazakov 2005-06-13 8:03 ` Ole-Hjalmar Kristensen 2 siblings, 0 replies; 41+ messages in thread From: Marius Amado Alves @ 2005-06-12 10:36 UTC (permalink / raw) To: comp.lang.ada As others have indicated, static expressions are evaluated at compile time, others at run time. That's the language rule. However, I tend to agree a compiler warning would be useful here, and I'm kind of surprised GNAT does not seem to have it (even with the -gnatwa "all warnings on" option). I would not be surprised if some GNAT *Pro* users have it. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 9:43 ` Lurker 2005-06-12 10:36 ` Marius Amado Alves @ 2005-06-12 11:53 ` Dmitry A. Kazakov 2005-06-13 8:03 ` Ole-Hjalmar Kristensen 2 siblings, 0 replies; 41+ messages in thread From: Dmitry A. Kazakov @ 2005-06-12 11:53 UTC (permalink / raw) On Sun, 12 Jun 2005 21:43:16 +1200, Lurker wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:79ahr0jozmqb$.10jzllrcjpmsv.dlg@40tude.net... > >>> Well, yes. But can't it tell that division by zero is always wrong >>> regardless? >> >> No, it is not, because it has a defined effect: Constraint_Error. Formally >> speaking division by zero is not a contract violation and thus cannot be >> "wrong". Consider the following: >> >> A : constant Integer := 0; >> B : Integer := 1; >> begin >> B := B / A; >> Put_Line ("Hello!"); >> exception >> when others => >> Put_Line ("Good bye!"); >> >> The above is a valid program, which should print "Good bye!". At the same >> time the following is *wrong*: >> >> A : constant Integer := 0; >> B : constant Integer := 1; >> C : Integer; >> begin >> C := B / A; >> >> B/A is a static expression, which has to have a value at compile-time. > > OK, I see you point. But, pratically speaking, the chances are that > that construct was an error. Perhaps a warning or some such would > be enough. If whoever wrote that was sure that's what they meant - fine. > But I was always under the impression that the Ada philosophy was > to avoid accidental mistakes as much as possible. And division by > zero sure should qualify as a suspect at least - not something that > just happily gets compiled. > >>>> Constraint_Error will be raised at runtime. >>> >>> It was. My question was - should it have been caught >>> at compile time instead? >> >> I don't think it should. A class of errors which cannot be detected at >> compile time cannot be compile-time errors. Or, in other words, if you >> cannot rely on the compiler, you should not pretend you can. (:-)) > > I'm afraid I don't follow your logic there. Do you really mean that > a constant declared as = 0 cannot be detected at compile time? > > Yes, the effects of using it to divide something may or may not be ok. > But that would equally apply to dividing a literal 1 by it, wouldn't it? > > (Again, I realise your point about static vs other expressions. > But c'mon, unless someone specifically allows and handles > cases like that, surely the safest bet would be to at least point > out that there is something fishy going on and a "moral equivalent" > of asking "are you sure"? The problem is in classification of this error (see also ARM 1.1.5): 1. language errors 2. run-time errors 3. bounded errors 4. logic errors You cannot require zero-divide be in 1 for obvious reasons. So it is in 2. The case of fully static expressions can be in 1 (and is), because static expressions are handled at compile-time. Now, if you want to bring <anything>/0 to the class 1, you should provide a carrier in the language to formulate it. The only one available in my view (let the language lawyers step in) is the type system. So a possible way could be "statically valued" types. Then you would be able define: function "/" (Left, Right : T) return T; -- This raises Constraint_Error (class 2) function "/" (Left : T; Right : static T) return T; require (Right /= 0); -- This gives a compile error (class 1), yet I can re-define it and -- implement, say, IEEE-like semantic of zero-divide Note, that the semantic of / can be re-defined. So in general case, even if 0 is static, the compiler cannot deduce that X/0 is an error without looking into the implementation of /. That's a halting problem. Therefore the only way I see, is a typed one, i.e. "statically valued" types. This step, or something similar, would have very serious consequences difficult to predict. In any case it would be not easy to do. If you ask for my opinion, then yes, I would like to have more influence on [partially] static expressions and the way one could ensure that something (complex) be evaluated at compile-time. But I bet that there are lot of people who want the opposite. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 9:43 ` Lurker 2005-06-12 10:36 ` Marius Amado Alves 2005-06-12 11:53 ` Dmitry A. Kazakov @ 2005-06-13 8:03 ` Ole-Hjalmar Kristensen 2 siblings, 0 replies; 41+ messages in thread From: Ole-Hjalmar Kristensen @ 2005-06-13 8:03 UTC (permalink / raw) At least it's better than what happened to me when I ported a Pascal program from a Norsk Data Pascal compiler to a Unix Pascal compiler. Someone had used 1/0 intentionally to force the program to abort at one place. The Unix Pascal compiler recognized that it could be computed at compile time, and promtply dumped core.... >>>>> "L" == Lurker <nowhere@nothing.com> writes: L> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message L> news:79ahr0jozmqb$.10jzllrcjpmsv.dlg@40tude.net... >> > Well, yes. But can't it tell that division by zero is always wrong >> > regardless? >> >> No, it is not, because it has a defined effect: Constraint_Error. Formally >> speaking division by zero is not a contract violation and thus cannot be >> "wrong". Consider the following: >> >> A : constant Integer := 0; >> B : Integer := 1; >> begin >> B := B / A; >> Put_Line ("Hello!"); >> exception >> when others => >> Put_Line ("Good bye!"); >> >> The above is a valid program, which should print "Good bye!". At the same >> time the following is *wrong*: >> >> A : constant Integer := 0; >> B : constant Integer := 1; >> C : Integer; >> begin >> C := B / A; >> >> B/A is a static expression, which has to have a value at compile-time. L> OK, I see you point. But, pratically speaking, the chances are that L> that construct was an error. Perhaps a warning or some such would L> be enough. If whoever wrote that was sure that's what they meant - fine. L> But I was always under the impression that the Ada philosophy was L> to avoid accidental mistakes as much as possible. And division by L> zero sure should qualify as a suspect at least - not something that L> just happily gets compiled. >> >> Constraint_Error will be raised at runtime. >> > >> > It was. My question was - should it have been caught >> > at compile time instead? >> >> I don't think it should. A class of errors which cannot be detected at >> compile time cannot be compile-time errors. Or, in other words, if you >> cannot rely on the compiler, you should not pretend you can. (:-)) L> I'm afraid I don't follow your logic there. Do you really mean that L> a constant declared as = 0 cannot be detected at compile time? L> Yes, the effects of using it to divide something may or may not be ok. L> But that would equally apply to dividing a literal 1 by it, wouldn't it? L> (Again, I realise your point about static vs other expressions. L> But c'mon, unless someone specifically allows and handles L> cases like that, surely the safest bet would be to at least point L> out that there is something fishy going on and a "moral equivalent" L> of asking "are you sure"? >> >> -- >> Regards, >> Dmitry A. Kazakov >> http://www.dmitry-kazakov.de -- C++: The power, elegance and simplicity of a hand grenade. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 8:39 ` Dmitry A. Kazakov 2005-06-12 9:43 ` Lurker @ 2005-06-12 13:10 ` Robert A Duff 2005-06-12 16:55 ` Jeffrey Carter 1 sibling, 1 reply; 41+ messages in thread From: Robert A Duff @ 2005-06-12 13:10 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > No, it is not, because it has a defined effect: Constraint_Error. Formally > speaking division by zero is not a contract violation and thus cannot be > "wrong". Consider the following: > > A : constant Integer := 0; > B : Integer := 1; > begin > B := B / A; > Put_Line ("Hello!"); > exception > when others => > Put_Line ("Good bye!"); > > The above is a valid program, which should print "Good bye!". At the same > time the following is *wrong*: > > A : constant Integer := 0; > B : constant Integer := 1; > C : Integer; > begin > C := B / A; > > B/A is a static expression, which has to have a value at compile-time. > > The difference is not in what the compiler might know, but in what it must > know. True, but the RM could easily define that differently. For example, in Ada 83, "1/0" was *not* considered a run-time error -- it must raise C_E at run time. That was changed in Ada 95. We could just as well add a rule that "B/0" is illegal. But the general idea is that we let compilers generate warnings in such cases, and don't worry too much about it in the RM. By the way, I believe your above example is wrong. In particular, it can print "Hello!". See RM-11.6. (This is why I don't like 11.6 -- reasonable programmers *think* the above should print "Good bye!", but 11.6 says it might not.) > > What has actually happened (outside that toy example) > > was that there was a constant declared in one place and used in > > many others. Someone went ahead and changed it (for a good > > reason) to zero. However, one of the uses of that constant was > > to divide by it. > > > >> Constraint_Error will be raised at runtime. > > > > It was. My question was - should it have been caught > > at compile time instead? > > I don't think it should. A class of errors which cannot be detected at > compile time cannot be compile-time errors. Or, in other words, if you > cannot rely on the compiler, you should not pretend you can. (:-)) Well, in Ada 83, the "class of errors" was "divide by zero". In Ada 95, that was split into "divide by zero in a static expression" and "divide by zero in a nonstatic expression" -- the former is a compile time error, whereas the latter is a run-time error. There's nothing illogical about splitting it further: "divide by zero when the Right operand is static" could be defined as a compile-time error. The problem is that if you try to define all the compile-time-detectable cases very precisely, it gets quite complicated. And however you define it, it *has* to be conservative. - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 13:10 ` Robert A Duff @ 2005-06-12 16:55 ` Jeffrey Carter 2005-06-13 3:22 ` Keith Thompson ` (2 more replies) 0 siblings, 3 replies; 41+ messages in thread From: Jeffrey Carter @ 2005-06-12 16:55 UTC (permalink / raw) Robert A Duff wrote: > Well, in Ada 83, the "class of errors" was "divide by zero". > In Ada 95, that was split into "divide by zero in a static expression" > and "divide by zero in a nonstatic expression" -- the former is a > compile time error, whereas the latter is a run-time error. > There's nothing illogical about splitting it further: > "divide by zero when the Right operand is static" could be defined > as a compile-time error. The problem is that if you try to define > all the compile-time-detectable cases very precisely, it gets quite > complicated. And however you define it, it *has* to be conservative. The problem, it seems to me, is that the developer may deliberately write a division of a variable by static zero for a number of reasons. He may want it to raise Constraint_Error at run time, or may have redefined "/" for the type of the variable to do something meaningful if the divisor is zero. This latter case invalidates an earlier example. The following should compile and output Integer'Last before terminating normally: with Ada.Text_IO; procedure Zero_Div is function "/" (Left : Integer; Right : Integer) return Integer is -- null; begin -- "/" if Right = 0 then return Integer'Last; else return Left / Right; end if; end "/"; A : constant Integer := 23; B : constant Integer := 0; begin -- Zero_Div Ada.Text_IO.Put_Line (Item => Integer'Image (A / B) ); end Zero_Div; -- Jeff Carter "Don't knock masturbation. It's sex with someone I love." Annie Hall 45 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 16:55 ` Jeffrey Carter @ 2005-06-13 3:22 ` Keith Thompson 2005-06-14 2:14 ` Jeffrey Carter 2005-06-13 8:47 ` Lurker 2005-06-13 12:19 ` Robert A Duff 2 siblings, 1 reply; 41+ messages in thread From: Keith Thompson @ 2005-06-13 3:22 UTC (permalink / raw) Jeffrey Carter <spam@spam.com> writes: [...] > The problem, it seems to me, is that the developer may deliberately > write a division of a variable by static zero for a number of > reasons. He may want it to raise Constraint_Error at run time, Surely "raise Constraint_Error;" is an easier way to do that (though I suppose I can imagine reasons for wanting to do it indirectly). > or may > have redefined "/" for the type of the variable to do something > meaningful if the divisor is zero. Then that's not division; it's just a call to a function whose name happens to be "/". -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 3:22 ` Keith Thompson @ 2005-06-14 2:14 ` Jeffrey Carter 0 siblings, 0 replies; 41+ messages in thread From: Jeffrey Carter @ 2005-06-14 2:14 UTC (permalink / raw) Keith Thompson wrote: > Surely "raise Constraint_Error;" is an easier way to do that (though I > suppose I can imagine reasons for wanting to do it indirectly). My sediments exactly. > Then that's not division; it's just a call to a function whose name > happens to be "/". True, but that's why the compiler can't say that "X / 0" is illegal. -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 16:55 ` Jeffrey Carter 2005-06-13 3:22 ` Keith Thompson @ 2005-06-13 8:47 ` Lurker 2005-06-14 2:19 ` Jeffrey Carter 2005-06-13 12:19 ` Robert A Duff 2 siblings, 1 reply; 41+ messages in thread From: Lurker @ 2005-06-13 8:47 UTC (permalink / raw) "Jeffrey Carter" <spam@spam.com> wrote in message news:JNZqe.3031$NX4.2109@newsread1.news.pas.earthlink.net... > The problem, it seems to me, is that the developer may deliberately > write a division of a variable by static zero for a number of reasons. > He may want it to raise Constraint_Error at run time, or may have > redefined "/" for the type of the variable to do something meaningful if > the divisor is zero. Sorry, that doesn't qualify. In my case there was no redifinition of "/" function. Compiler, of course, knows that since it has to resolve the reference anyway. So it did know that the "/" in question was your regular pre-defined division. Since it knows that, then the only reason to allow that to pass would be for intentional exception raising. But as someone else pointed out you can just go ahead and use "raise exception" statement if you really want that. Basically, it seems to me very hard to think of a situation where that division would be a bona-fide, intended thing. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 8:47 ` Lurker @ 2005-06-14 2:19 ` Jeffrey Carter 2005-06-14 8:35 ` Keith Thompson 0 siblings, 1 reply; 41+ messages in thread From: Jeffrey Carter @ 2005-06-14 2:19 UTC (permalink / raw) Lurker wrote: > Sorry, that doesn't qualify. In my case there was no redifinition > of "/" function. Compiler, of course, knows that since it has to > resolve the reference anyway. So it did know that the "/" in > question was your regular pre-defined division. Since it knows > that, then the only reason to allow that to pass would be for > intentional exception raising. But as someone else pointed > out you can just go ahead and use "raise exception" statement > if you really want that. Basically, it seems to me very hard to > think of a situation where that division would be a bona-fide, > intended thing. I suppose a compiler could tell if "/" had been redefined for a type, and produce warnings only in the case where it had not, but I don't know of any compilers that do. There are situations where exceptions are not allowed by local rules, and some people will always try to find ways around such rules, but in general I'd expect a raise statement in most cases. -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-14 2:19 ` Jeffrey Carter @ 2005-06-14 8:35 ` Keith Thompson 0 siblings, 0 replies; 41+ messages in thread From: Keith Thompson @ 2005-06-14 8:35 UTC (permalink / raw) Jeffrey Carter <spam@spam.com> writes: [...] > I suppose a compiler could tell if "/" had been redefined for a type, > and produce warnings only in the case where it had not, but I don't > know of any compilers that do. I do: % gcc --version gcc (GCC) 4.0.0 Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % cat -n foo.adb 1 procedure Foo is 2 X : Integer := 1; 3 Y : Integer := 1; 4 begin 5 declare 6 function "/"(Left, Right: Integer) return Integer is 7 begin 8 return Right; 9 end "/"; 10 begin 11 X := X / 0; 12 X := 1 / 0; 13 end; 14 Y := Y / 0; 15 Y := 1 / 0; 16 end Foo; % gcc -c foo.adb foo.adb:14:14: warning: division by zero foo.adb:14:14: warning: "Constraint_Error" will be raised at run time foo.adb:15:12: division by zero foo.adb:15:12: static expression raises "Constraint_Error" I'd be surprised if this weren't the case. By the time the compiler is deciding whether to issue a warning, it knows that the "/" being invoked is a user-defined operator rather than a predefined operator (and probably doesn't care that its name is "/"). If a compiler issued a warning on a call to a user-defined "/" function with a second parameter of 0, I'd consider it a bug (unless it was a result of an analysis of the actual function). -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 16:55 ` Jeffrey Carter 2005-06-13 3:22 ` Keith Thompson 2005-06-13 8:47 ` Lurker @ 2005-06-13 12:19 ` Robert A Duff 2005-06-14 2:31 ` Jeffrey Carter 2005-06-14 8:21 ` Lurker 2 siblings, 2 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-13 12:19 UTC (permalink / raw) Jeffrey Carter <spam@spam.com> writes: > Robert A Duff wrote: > > Well, in Ada 83, the "class of errors" was "divide by zero". > > In Ada 95, that was split into "divide by zero in a static expression" > > and "divide by zero in a nonstatic expression" -- the former is a > > compile time error, whereas the latter is a run-time error. > > There's nothing illogical about splitting it further: > > "divide by zero when the Right operand is static" could be defined > > as a compile-time error. The problem is that if you try to define > > all the compile-time-detectable cases very precisely, it gets quite > > complicated. And however you define it, it *has* to be conservative. > > The problem, it seems to me, is that the developer may deliberately > write a division of a variable by static zero for a number of > reasons. He may want it to raise Constraint_Error at run time,... It's hard to come up with legitimate examples of that. As others have pointed out, "raise C_E" is usually the best way to raise C_E. Here's an example that agrees with your point: Suppose I have a constant Widgets that is different on different operating systems. So I create two versions of the same package, and the Windows version says "Widgets: constant Integer := 23;" and the Unix version says "Widgets: constant Integer := 0;". I have some configuration scripts to pick the right version of the source code to compile. (This is a common way of dealing with OS dependencies.) Now I have a variable Gizmos, and I want to print out the numbers of Gizmos per Widget (when that's meaningful). In *portable* code, I might want to write: if Widgets = 0 then Put_Line("Unknown"); else Put_Line(Image(Gizmos/Widgets)); end if; If divide by zero were illegal at compile time, even in unreachable code, the above would be annoying illegal on Unix. So I would have to move the above if statement into the OS-specific files, thus increasing their size -- a Bad Thing. Or, I would have to make Widgets nonstatic, which might be damaging for other reasons. (In fact, if Gizmos is static, then the above *is* illegal in Ada 95, but not Ada 83.) Can anybody think of a better example (i.e. one that does not involve extra-lingual features such as OS-specific source code versions)? >... or may > have redefined "/" for the type of the variable to do something > meaningful if the divisor is zero. The rules about static expressions do not apply to user-defined operators, which can do anything you like. > This latter case invalidates an earlier example. The following should > compile and output Integer'Last before terminating normally: > > with Ada.Text_IO; > procedure Zero_Div is > function "/" (Left : Integer; Right : Integer) return Integer is > -- null; > begin -- "/" > if Right = 0 then > return Integer'Last; > else > return Left / Right; Careful! That looks like an infinite recursion. You need to do some horsing around to get at the predefined "/", so you can call it from the user-defined one. > end if; > end "/"; > > A : constant Integer := 23; > B : constant Integer := 0; > begin -- Zero_Div > Ada.Text_IO.Put_Line (Item => Integer'Image (A / B) ); > end Zero_Div; - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 12:19 ` Robert A Duff @ 2005-06-14 2:31 ` Jeffrey Carter 2005-06-14 8:21 ` Lurker 1 sibling, 0 replies; 41+ messages in thread From: Jeffrey Carter @ 2005-06-14 2:31 UTC (permalink / raw) Robert A Duff wrote: > It's hard to come up with legitimate examples of that. > As others have pointed out, "raise C_E" is usually the > best way to raise C_E. I agree, though they do exist. > Here's an example that agrees with your point: Good example. > (In fact, if Gizmos is static, then the above *is* illegal in Ada 95, > but not Ada 83.) Are you sure? In my examples, both operands are static. > The rules about static expressions do not apply to user-defined > operators, which can do anything you like. This is an area of Ada 95 that sometimes bites me because I got used to the Ada-83 rules. In Ada 83, any static universal expression was evaluated at compile time. In Ada 95, if the context of the expression has a type, the operator for that type must be invoked; since that operator may be redefined, the expression must be evaluated at run time. > Careful! That looks like an infinite recursion. Well spotted. I could admit that I didn't pay attention to that branch because it would never be invoked, but instead I'll claim that infinite recursion was the desired behavior if you try to divide by anything other than zero. -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 12:19 ` Robert A Duff 2005-06-14 2:31 ` Jeffrey Carter @ 2005-06-14 8:21 ` Lurker 2005-06-14 20:22 ` Randy Brukardt 2005-06-28 21:22 ` Robert A Duff 1 sibling, 2 replies; 41+ messages in thread From: Lurker @ 2005-06-14 8:21 UTC (permalink / raw) "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message news:wccfyvm78k0.fsf@shell01.TheWorld.com... > Now I have a variable Gizmos, and I want to print out the > numbers of Gizmos per Widget (when that's meaningful). > In *portable* code, I might want to write: > > if Widgets = 0 then > Put_Line("Unknown"); > else > Put_Line(Image(Gizmos/Widgets)); > end if; > > If divide by zero were illegal at compile time, even in unreachable > code, the above would be annoying illegal on Unix. Interesting example. I guess I'm taking it a bit on a tangent now but how does that square off with RM 11.6.5 which says in part: ... The exception need be raised by the implementation only if, in the absence of raising it, the value of this undefined result would have some effect on the external interactions of the program ... Yes, I know it's just an implementation permission and so doesn't define the language. Yet, the idea seems to be that if there is no possible observable effect then it's ok. Shouldn't the same logic apply in your example as well? ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-14 8:21 ` Lurker @ 2005-06-14 20:22 ` Randy Brukardt 2005-06-28 21:22 ` Robert A Duff 1 sibling, 0 replies; 41+ messages in thread From: Randy Brukardt @ 2005-06-14 20:22 UTC (permalink / raw) "Lurker" <nowhere@nothing.com> wrote in message news:_pwre.7121$U4.1023104@news.xtra.co.nz... > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > news:wccfyvm78k0.fsf@shell01.TheWorld.com... > > > Now I have a variable Gizmos, and I want to print out the > > numbers of Gizmos per Widget (when that's meaningful). > > In *portable* code, I might want to write: > > > > if Widgets = 0 then > > Put_Line("Unknown"); > > else > > Put_Line(Image(Gizmos/Widgets)); > > end if; > > > > If divide by zero were illegal at compile time, even in unreachable > > code, the above would be annoying illegal on Unix. > > Interesting example. I guess I'm taking it a bit on a tangent now > but how does that square off with RM 11.6.5 which says in part: > > ... The exception need be raised by the implementation only if, in the > absence of raising it, the value of this undefined result would have some > effect on the external interactions of the program ... > > Yes, I know it's just an implementation permission and so doesn't define > the language. Yet, the idea seems to be that if there is no possible > observable > effect then it's ok. Shouldn't the same logic apply in your example as well? No, because 11.6 doesn't apply to Legality Rules, only runtime effects. If the program is illegal, it can hardly have a runtime effect, and certainly it is not raising any exceptions. Randy. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-14 8:21 ` Lurker 2005-06-14 20:22 ` Randy Brukardt @ 2005-06-28 21:22 ` Robert A Duff 2005-06-29 5:50 ` Lurker 2005-06-29 9:20 ` Lurker 1 sibling, 2 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-28 21:22 UTC (permalink / raw) "Lurker" <nowhere@nothing.com> writes: > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > news:wccfyvm78k0.fsf@shell01.TheWorld.com... > > > Now I have a variable Gizmos, and I want to print out the > > numbers of Gizmos per Widget (when that's meaningful). > > In *portable* code, I might want to write: > > > > if Widgets = 0 then > > Put_Line("Unknown"); > > else > > Put_Line(Image(Gizmos/Widgets)); > > end if; > > > > If divide by zero were illegal at compile time, even in unreachable > > code, the above would be annoying illegal on Unix. > > Interesting example. I guess I'm taking it a bit on a tangent now > but how does that square off with RM 11.6.5 which says in part: > > ... The exception need be raised by the implementation only if, in the > absence of raising it, the value of this undefined result would have some > effect on the external interactions of the program ... > > Yes, I know it's just an implementation permission and so doesn't define > the language. Yet, the idea seems to be that if there is no possible > observable > effect then it's ok. Shouldn't the same logic apply in your example as well? 11.6(5) is all about run time effects. If divide by zero were illegal (which means at compile time), then 11.6 would not apply. 11.6 is also (as you said) all about implementation permissions -- i.e. not portable. I would hope a legality rule in this area would be portable. - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-28 21:22 ` Robert A Duff @ 2005-06-29 5:50 ` Lurker 2005-06-29 13:27 ` Robert A Duff 2005-06-29 13:50 ` Dmitry A. Kazakov 2005-06-29 9:20 ` Lurker 1 sibling, 2 replies; 41+ messages in thread From: Lurker @ 2005-06-29 5:50 UTC (permalink / raw) "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message news:wccy88ugorw.fsf@shell01.TheWorld.com... > 11.6(5) is all about run time effects. If divide by zero were illegal > (which means at compile time), then 11.6 would not apply. Which brings us back to my original question - why is it legal? Please excuse all examples of custom "/" definitions. Let's assume we are talking about predefined division operation on integers. Why would division by zero be allowed? (If you want to redefine your operations, then all bets are off of course, but what about the default ones?) ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 5:50 ` Lurker @ 2005-06-29 13:27 ` Robert A Duff 2005-06-29 13:54 ` Dmitry A. Kazakov 2005-06-30 1:19 ` Lurker 2005-06-29 13:50 ` Dmitry A. Kazakov 1 sibling, 2 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-29 13:27 UTC (permalink / raw) "Lurker" <nowhere@nothing.com> writes: > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > news:wccy88ugorw.fsf@shell01.TheWorld.com... > > > 11.6(5) is all about run time effects. If divide by zero were illegal > > (which means at compile time), then 11.6 would not apply. > > Which brings us back to my original question - why is it legal? Just to be cleear, we're talking about whether X/Y should be illegal when Y is a static expression equal to 0. It is illegal if X is also static, but it is legal if X is nonstatic. The reason is that it simplifies the language definition. For any particular "kind" of error, the language design style used for Ada is to choose one of: - always detect this error at compile time - always detect this error at run time For division by zero, it is believed to be too restrictive to detect it at compile time. Therefore it's a run-time error. And we trust compilers to give warnings in cases that can be detected at compile time. But it would complicate the language definition to describe such cases, and it would not be clear how "smart" to require the compiler to be. Static expressions are special, though: the compiler needs to know the value of the expression, at last sometimes. We have to make things like this: T'First(1/0) illegal, for example, because the type of that expression depends on the value of 1/0, which doesn't make sense. (In the above, I'm ignoring the rare cases of errors that are not detected at all, or are detected at link time, etc.) > Please excuse all examples of custom "/" definitions. Let's assume > we are talking about predefined division operation on integers. I agree -- everybody is confusing the issue by talking about user-defined functions that happen to be called "/". We're talking about predefined division only. > Why would division by zero be allowed? (If you want to redefine > your operations, then all bets are off of course, but what about > the default ones?) - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 13:27 ` Robert A Duff @ 2005-06-29 13:54 ` Dmitry A. Kazakov 2005-06-29 16:03 ` Robert A Duff 2005-06-30 1:19 ` Lurker 1 sibling, 1 reply; 41+ messages in thread From: Dmitry A. Kazakov @ 2005-06-29 13:54 UTC (permalink / raw) On 29 Jun 2005 09:27:01 -0400, Robert A Duff wrote: > I agree -- everybody is confusing the issue by talking about > user-defined functions that happen to be called "/". Why there should be any difference? User-defined "/" is as good (bad) as the predefined one. If the contract reads: "the second argument is never 0", then it is absolutely no matter what "/" does! The contract is broken on the caller's side. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 13:54 ` Dmitry A. Kazakov @ 2005-06-29 16:03 ` Robert A Duff 0 siblings, 0 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-29 16:03 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > On 29 Jun 2005 09:27:01 -0400, Robert A Duff wrote: > > > I agree -- everybody is confusing the issue by talking about > > user-defined functions that happen to be called "/". > > Why there should be any difference? User-defined "/" is as good (bad) as > the predefined one. If the contract reads: "the second argument is never > 0", then it is absolutely no matter what "/" does! The contract is broken > on the caller's side. Because in Ada, the "contract" is written starting with "--", and the compiler can't understand it! - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 13:27 ` Robert A Duff 2005-06-29 13:54 ` Dmitry A. Kazakov @ 2005-06-30 1:19 ` Lurker 2005-06-30 11:16 ` Stuart Palin 1 sibling, 1 reply; 41+ messages in thread From: Lurker @ 2005-06-30 1:19 UTC (permalink / raw) "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message news:wcck6kdguoq.fsf@shell01.TheWorld.com... > "Lurker" <nowhere@nothing.com> writes: > > > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > > news:wccy88ugorw.fsf@shell01.TheWorld.com... > > > > > 11.6(5) is all about run time effects. If divide by zero were illegal > > > (which means at compile time), then 11.6 would not apply. > > > > Which brings us back to my original question - why is it legal? > > Just to be cleear, we're talking about whether X/Y should be illegal > when Y is a static expression equal to 0. It is illegal if X is also > static, but it is legal if X is nonstatic. Correct. > The reason is that it simplifies the language definition. You don't seem to find any problem with complicating the language definition in the case of static expressions though. And, detecting division by static zero should be a non-issue really. > For division by zero, it is believed to be too restrictive to detect it > at compile time. Why? I mean, you have a static constant which is defined to be equal to zero. Surely compiler knows it's value at compile time (and also the meaning of "/" operator it is used in). > Therefore it's a run-time error. And we trust > compilers to give warnings in cases that can be detected at compile > time. But it would complicate the language definition to describe such > cases, and it would not be clear how "smart" to require the compiler to > be. Sorry, I still don't see how complex it would be. If an expression is static, compiler knows it at compile time, correct? So let's say the rule is that predefined division operation is illegal if the static divisor evaluates to zero. This is already done in the case of static/static expression so it can't be impossible. The only argument in favor of allowing it wold be some legitimate use for it but, except your configuration example, I haven't seen any so far. > Static expressions are special, though: the compiler needs to know the > value of the expression, at last sometimes. We have to make things like > this: > > T'First(1/0) > > illegal, for example, because the type of that expression depends on the > value of 1/0, which doesn't make sense. If I understood your previous comments correctly, 1/0 is already illegal, no matter where it's used. Or have you changed your mind and now say that the use define legality even in static expressions? > > Please excuse all examples of custom "/" definitions. Let's assume > > we are talking about predefined division operation on integers. > > I agree -- everybody is confusing the issue by talking about > user-defined functions that happen to be called "/". > We're talking about predefined division only. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-30 1:19 ` Lurker @ 2005-06-30 11:16 ` Stuart Palin 0 siblings, 0 replies; 41+ messages in thread From: Stuart Palin @ 2005-06-30 11:16 UTC (permalink / raw) Lurker wrote: > > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > > The reason is that it simplifies the language definition. > > You don't seem to find any problem with complicating > the language definition in the case of static expressions though. > And, detecting division by static zero should be a non-issue > really. But evaluating static expressions is a general rule that can support error detection in a wide range of cases - basically all the predefined operators. Consider: type T is range 1..10; x, y : T; ... x := 5 + 6; -- Constraint error will be raised! or y := x + 10; -- Constraint Error will be raised! [GNAT produces warnings that constraint error will be raised in these cases] If you are adding a rule for "/", what about the other operators (which also include "mod" and "rem"). If you don't have the additional rules the language starts to appear arbitrary: now you have to start remembering what all the arbitrary rules are. As has been said elsewhere, you can add the rules but they make the compiler more complex (and if you are not careful can interact with other rules in unexpected ways). It is right that the Ada standard considers both the benefit and cost of the rules. Personally I think the standard has got it right in this case: it has defined a generic rule that has benefits and seems to be little cost to the compiler (it will most likely want to evaluate static expressions at compile time). > Sorry, I still don't see how complex it would be. If an expression is > static, compiler knows it at compile time, correct? So let's say the > rule is that predefined division operation is illegal if the static > divisor evaluates to zero. But how complicated will the language become if everyone's pet 'simple rule' got put in. There are tools available for carrying out much more detailed analysis of code behaviour (e.g. SPARK & Polyspace). For people really concerned with errors in their code (not just divide by zero) they offer automated ways of detecting them. Regards -- Stuart ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 5:50 ` Lurker 2005-06-29 13:27 ` Robert A Duff @ 2005-06-29 13:50 ` Dmitry A. Kazakov 2005-06-29 16:07 ` Robert A Duff 1 sibling, 1 reply; 41+ messages in thread From: Dmitry A. Kazakov @ 2005-06-29 13:50 UTC (permalink / raw) On Wed, 29 Jun 2005 17:50:43 +1200, Lurker wrote: > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > news:wccy88ugorw.fsf@shell01.TheWorld.com... > >> 11.6(5) is all about run time effects. If divide by zero were illegal >> (which means at compile time), then 11.6 would not apply. > > Which brings us back to my original question - why is it legal? Because within *one* type [Integer in this case] it is a halting problem: declare A : Integer := 1; B : Integer; begin if HALT (x) then B := 0; else B := 1; end if; A := A / B; end; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 13:50 ` Dmitry A. Kazakov @ 2005-06-29 16:07 ` Robert A Duff 2005-06-30 8:27 ` Dmitry A. Kazakov 0 siblings, 1 reply; 41+ messages in thread From: Robert A Duff @ 2005-06-29 16:07 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > On Wed, 29 Jun 2005 17:50:43 +1200, Lurker wrote: > > > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > > news:wccy88ugorw.fsf@shell01.TheWorld.com... > > > >> 11.6(5) is all about run time effects. If divide by zero were illegal > >> (which means at compile time), then 11.6 would not apply. > > > > Which brings us back to my original question - why is it legal? > > Because within *one* type [Integer in this case] it is a halting problem: > > declare > A : Integer := 1; > B : Integer; > begin > if HALT (x) then > B := 0; > else > B := 1; > end if; > A := A / B; > end; Sorry, but I think you were confused by my sloppy wording. The question was not whether divide-by-zero should be illegal in the general case. The question was whether X/Y should be illegal when Y is static, but X is not. Even in your example above, there's a good argument that the compiler should (optionally) warn. That example looks buggy to me! - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 16:07 ` Robert A Duff @ 2005-06-30 8:27 ` Dmitry A. Kazakov 0 siblings, 0 replies; 41+ messages in thread From: Dmitry A. Kazakov @ 2005-06-30 8:27 UTC (permalink / raw) On 29 Jun 2005 12:07:48 -0400, Robert A Duff wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> On Wed, 29 Jun 2005 17:50:43 +1200, Lurker wrote: >> >>> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message >>> news:wccy88ugorw.fsf@shell01.TheWorld.com... >>> >>>> 11.6(5) is all about run time effects. If divide by zero were illegal >>>> (which means at compile time), then 11.6 would not apply. >>> >>> Which brings us back to my original question - why is it legal? >> >> Because within *one* type [Integer in this case] it is a halting problem: >> >> declare >> A : Integer := 1; >> B : Integer; >> begin >> if HALT (x) then >> B := 0; >> else >> B := 1; >> end if; >> A := A / B; >> end; > > Sorry, but I think you were confused by my sloppy wording. > The question was not whether divide-by-zero should be illegal > in the general case. The question was whether X/Y should be > illegal when Y is static, but X is not. Yes, this is why I mentioned "one type". Without breaking the type system, it would be difficult to make X/0 illegal. A possible scenario: Universal_Integer is converted to Integer and then "/" is called. Let we want zero divide to be illegal. Then we could introduce: function "/" (Left : Integer; Right : Universal_Integer) return Integer; overloaded with what we have now: function "/" (Left, Right : Integer) return Integer; function "/" (Left, Right : Universal_Integer) return Universal_Integer; Fine, but what would happen if "/" gets overridden? This would open a can of worms, because the result of X/Y would depend on whether Y is static! OK, it already depends if both are static. But making it dependant on the basis of individual values? This may lead to fine effects very difficult to catch, so in the end, safety would rather lost than gained. > Even in your example above, there's a good argument that the compiler > should (optionally) warn. That example looks buggy to me! Yes. I think that warning about run-time C_E would be more appropriate here. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-28 21:22 ` Robert A Duff 2005-06-29 5:50 ` Lurker @ 2005-06-29 9:20 ` Lurker 2005-06-29 9:49 ` Christoph Grein 2005-06-29 13:40 ` Robert A Duff 1 sibling, 2 replies; 41+ messages in thread From: Lurker @ 2005-06-29 9:20 UTC (permalink / raw) "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message news:wccy88ugorw.fsf@shell01.TheWorld.com... > 11.6(5) is all about run time effects. If divide by zero were illegal > (which means at compile time), then 11.6 would not apply. 11.6 is also > (as you said) all about implementation permissions -- i.e. not > portable. I would hope a legality rule in this area would be portable. OK, I don't want to get *too* deep into the language wars sort of thing. My surprise was quite pragmatic - I was called in (as a consultant) to investigate and fix a problem that led to actual program crash in production. The reason for that crash, as it happened, was division by zero in some obscure and rarely used part of the code. Now, I would understand it if it was a variable which is generally unsolvable. But a constant? At first I thought it must be a bug in this particular compiler version. But since then I've had quite a few replies stating that's how it should be. So I don't know anymore... ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 9:20 ` Lurker @ 2005-06-29 9:49 ` Christoph Grein 2005-06-29 10:40 ` Lurker 2005-06-29 13:40 ` Robert A Duff 1 sibling, 1 reply; 41+ messages in thread From: Christoph Grein @ 2005-06-29 9:49 UTC (permalink / raw) To: CLA declare C: constant := 0; D: constant := 1; A: constant Integer := D / C; -- static, illegal function "/" (Left, Right: Integer) return Integer is begin return 1; end "/"; E: constant := D / C; -- static, illegal F: constant Integer := D / C; -- legal, not static, uses overridden "/" begin null; end; Lurker wrote: >"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message >news:wccy88ugorw.fsf@shell01.TheWorld.com... > > > >>11.6(5) is all about run time effects. If divide by zero were illegal >>(which means at compile time), then 11.6 would not apply. 11.6 is also >>(as you said) all about implementation permissions -- i.e. not >>portable. I would hope a legality rule in this area would be portable. >> >> > >OK, I don't want to get *too* deep into the language wars sort >of thing. My surprise was quite pragmatic - I was called in (as a >consultant) to investigate and fix a problem that led to actual program >crash in production. The reason for that crash, as it happened, was >division by zero in some obscure and rarely used part of the code. >Now, I would understand it if it was a variable which is generally >unsolvable. But a constant? At first I thought it must be a bug in this >particular compiler version. But since then I've had quite a few replies >stating that's how it should be. So I don't know anymore... > > >_______________________________________________ >comp.lang.ada mailing list >comp.lang.ada@ada-france.org >http://www.ada-france.org/mailman/listinfo/comp.lang.ada > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 9:49 ` Christoph Grein @ 2005-06-29 10:40 ` Lurker 2005-06-29 11:04 ` Jeff Creem 0 siblings, 1 reply; 41+ messages in thread From: Lurker @ 2005-06-29 10:40 UTC (permalink / raw) "Christoph Grein" <Christoph.Grein@eurocopter.com> wrote in message news:mailman.114.1120039635.17633.comp.lang.ada@ada-france.org... > declare > C: constant := 0; > D: constant := 1; > A: constant Integer := D / C; -- static, illegal > function "/" (Left, Right: Integer) return Integer is > begin > return 1; > end "/"; > E: constant := D / C; -- static, illegal > F: constant Integer := D / C; -- legal, not static, uses overridden "/" > begin > null; > end; Well, first of all, redefinition of "/" was not permitted (or there would be no point) But more to the issue, I have said that the problem was the use of default division operator on an integer number. Yes, I can write any sorts of custom functions called "/" too. So what? The question was if or when compiler should catch trivial mistakes like that and, at least, warn you "Are you sure?" ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 10:40 ` Lurker @ 2005-06-29 11:04 ` Jeff Creem 2005-06-29 12:28 ` Martin Dowie 0 siblings, 1 reply; 41+ messages in thread From: Jeff Creem @ 2005-06-29 11:04 UTC (permalink / raw) Lurker wrote: > Well, first of all, redefinition of "/" was not permitted (or there would be > no point) > > But more to the issue, I have said that the problem was the use of default > division operator on an integer number. > > Yes, I can write any sorts of custom functions called "/" too. So what? > > The question was if or when compiler should catch trivial mistakes > like that and, at least, warn you "Are you sure?" > > If you are talking about a warning you are into the realm of "quality of implementation". Given your previous examples (ignoring some of the red herrings on the thread) it looks to me like it would be reasonable for a compiler to warn you. Certainly various compilers I have used over the years have provided warnings for less useful potentially dangerous conditions. That is not at all the same thing as saying a compiler that does not warn you is broken.... However, if you are a paying customer for the compiler you are using it seems worth a phone call to the vendor. In the end (to some extent) it does not matter what the LRM says. You are a customer and are unhappy and what you are unhappy about is a case that causes a crash in real code and which at first glance (and second glance) appears to be something the compiler could reaonable detect. If you really are looking to statically detect cases that are somewhat more non-trivial then I'd suggest something like http://www.polyspace.com/ Note that with a large pre-existing code base it seems possible (likely?) that this latter solution could find a lot of false positives but it is hard to know until one tries. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 11:04 ` Jeff Creem @ 2005-06-29 12:28 ` Martin Dowie 0 siblings, 0 replies; 41+ messages in thread From: Martin Dowie @ 2005-06-29 12:28 UTC (permalink / raw) Jeff Creem wrote: > If you really are looking to statically detect cases that are somewhat > more non-trivial then I'd suggest something like > > http://www.polyspace.com/ > > Note that with a large pre-existing code base it seems possible > (likely?) that this latter solution could find a lot of false > positives but it is hard to know until one tries. Yup but it's less of a problem for Ada users than for C/C++ users (trust me)! :-) ...and as there is a specific "Div Zero" check, so you can simply filter on this one check and inspect anything highlighted. Cheers -- Martin ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-29 9:20 ` Lurker 2005-06-29 9:49 ` Christoph Grein @ 2005-06-29 13:40 ` Robert A Duff 1 sibling, 0 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-29 13:40 UTC (permalink / raw) "Lurker" <nowhere@nothing.com> writes: > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message > news:wccy88ugorw.fsf@shell01.TheWorld.com... > > > 11.6(5) is all about run time effects. If divide by zero were illegal > > (which means at compile time), then 11.6 would not apply. 11.6 is also > > (as you said) all about implementation permissions -- i.e. not > > portable. I would hope a legality rule in this area would be portable. > > OK, I don't want to get *too* deep into the language wars sort > of thing. Language wars? To have a language war, you have to crosspost to two or more newsgroups, and insult the advocates of one or more languges. ;-) >... My surprise was quite pragmatic - I was called in (as a > consultant) to investigate and fix a problem that led to actual program > crash in production. The reason for that crash, as it happened, was > division by zero in some obscure and rarely used part of the code. > Now, I would understand it if it was a variable which is generally > unsolvable. But a constant? At first I thought it must be a bug in this > particular compiler version. But since then I've had quite a few replies > stating that's how it should be. So I don't know anymore... Whether it's a compiler bug or not is a matter of opinion. It depends whether you think compilers ought to be smart enough to detect the case you're interested in (which, as I recall, was something like X/0, where X is not static). I think it's a bug, and I would report it. You can convince the compile vendor that it's a bug by giving them money. ;-) But this case is *not* a violation of the Ada standard. The compiler *should* detect this case (IMHO), but is not required to do so by the standard. There are many other cases compilers *should* detect. For example: package P is Y: constant Integer; private Y: constant Integer := 0; end P; ... X/P.Y ... -- compiler should warn, but P.Y is *not* static and: procedure P(X: Integer) is Y: Integer; begin if ... then Y := 0; ... X/Y ... -- compiler should warn else Y := 7; end if; end P; I'm not sure about this one: procedure P(X: Integer) is Y: Integer; begin if ... then Y := 0; else Y := 7; end if; ... X/Y ... -- should compiler warn? end P; There's probably a bug, but maybe not. - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
[parent not found: <5sana1pm436l6vboifijqblu0irf84afkr@4ax.com>]
* Re: Division by zero [not found] ` <5sana1pm436l6vboifijqblu0irf84afkr@4ax.com> @ 2005-06-12 17:38 ` Simon Wright 0 siblings, 0 replies; 41+ messages in thread From: Simon Wright @ 2005-06-12 17:38 UTC (permalink / raw) Dennis Lee Bieber <wlfraed@ix.netcom.com> writes: > On Sun, 12 Jun 2005 15:04:17 +1200, "Lurker" <nowhere@nothing.com> > declaimed the following in comp.lang.ada: > > >> >> It was. My question was - should it have been caught >> at compile time instead? >> > Possibly not... Isn't 0/0 allowed in IEEE -> giving one of those > strange NaN type results... These are integers, though, and GNAT catches integer divide-by-zero. For floats, you can either check 'Valid (Infs and NaNs aren't) or use a constrained subtype: type My_Float is Float range Float'First .. Float'Last; which will give you the constraint error you'd expect when you assign an invalid result to it. Well, come to think I didn't try with NaN ... ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-11 21:03 Division by zero Lurker 2005-06-12 2:00 ` David C. Hoos, Sr. @ 2005-06-12 12:21 ` Robert A Duff 2005-06-12 22:53 ` Georg Bauhaus 2 siblings, 0 replies; 41+ messages in thread From: Robert A Duff @ 2005-06-12 12:21 UTC (permalink / raw) "Lurker" <nowhere@nothing.com> writes: > Hi, > > I'm curios about the problem which I discovered by accident. > The code below is of course very much reduced to show > the it: > > function x(a: integer) return integer is > > some_constant: constant := 0; > > begin > > -- return 1/some_constant; -- line 1 > > -- return a/some_constant; -- line 2 > > end; Static expressions that raise exceptions are illegal, so the compiler must give an error on line 1. The compiler should complain about line 2 (a "warning" or some such), but it is not required to by the Standard. > If line 1 is uncommented compiler (Gnat 3.15 for Widows) > > produces the expected error about division by zero. > > If line 2 is uncommented it passes compilation with no problem. > > Surely that's not right? Or did I miss something? This behavior conforms to the RM. But I suspect that if you sent a bug report about line 2, the implementer will fix it -- it's an obvious and easy-to-detect case that is most likely an error. - Bob ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-11 21:03 Division by zero Lurker 2005-06-12 2:00 ` David C. Hoos, Sr. 2005-06-12 12:21 ` Robert A Duff @ 2005-06-12 22:53 ` Georg Bauhaus 2005-06-13 8:34 ` Lurker 2 siblings, 1 reply; 41+ messages in thread From: Georg Bauhaus @ 2005-06-12 22:53 UTC (permalink / raw) Lurker wrote: > function x(a: integer) return integer is ... > -- return a/some_constant; -- line 2 > > end; > If line 2 is uncommented it passes compilation with no problem. > > Surely that's not right? Or did I miss something? You could request more warnings: $ gnatgcc -c -gnatv -gnatwa x.adb GNAT 3.4.4 20050314 (prerelease) (Debian 3.4.3-13) Copyright 1992-2004 Free Software Foundation, Inc. Compiling: x.adb (source file time stamp: 2005-06-12 22:47:07) 9. return a/some_constant; -- line 2 | >>> warning: division by zero >>> warning: "Constraint_Error" will be raised at run time 15 lines: No errors, 2 warnings ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-12 22:53 ` Georg Bauhaus @ 2005-06-13 8:34 ` Lurker 2005-06-13 8:54 ` Marius Amado Alves 0 siblings, 1 reply; 41+ messages in thread From: Lurker @ 2005-06-13 8:34 UTC (permalink / raw) "Georg Bauhaus" <bauhaus@futureapps.de> wrote in message news:42aca05a$0$24379$9b4e6d93@newsread2.arcor-online.net... > You could request more warnings: > > $ gnatgcc -c -gnatv -gnatwa x.adb > > GNAT 3.4.4 20050314 (prerelease) (Debian 3.4.3-13) Copyright 1992-2004 Free Software Foundation, Inc. > > Compiling: x.adb (source file time stamp: 2005-06-12 22:47:07) > > 9. return a/some_constant; -- line 2 > | > >>> warning: division by zero > >>> warning: "Constraint_Error" will be raised at run time That's a new one for me. Yes - that's exactly what I would expect. However, not everyone is running Debian and there were other posters in this group who confirmed that Windows version doesn't flag it as a warning even with full warnings on. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 8:34 ` Lurker @ 2005-06-13 8:54 ` Marius Amado Alves 2005-06-13 17:59 ` Simon Wright 0 siblings, 1 reply; 41+ messages in thread From: Marius Amado Alves @ 2005-06-13 8:54 UTC (permalink / raw) To: comp.lang.ada On 13 Jun 2005, at 09:34, Lurker wrote: > "Georg Bauhaus" <bauhaus@futureapps.de> wrote in message > news:42aca05a$0$24379$9b4e6d93@newsread2.arcor-online.net... >> You could request more warnings: >> >> $ gnatgcc -c -gnatv -gnatwa x.adb >> >> GNAT 3.4.4 20050314 (prerelease) (Debian 3.4.3-13) Copyright 1992-2004 > Free Software Foundation, Inc. >> >> Compiling: x.adb (source file time stamp: 2005-06-12 22:47:07) >> >> 9. return a/some_constant; -- line 2 >> | >>>>> warning: division by zero >>>>> warning: "Constraint_Error" will be raised at run time > > That's a new one for me. Yes - that's exactly what I would expect. > However, not everyone is running Debian and there were other > posters in this group who confirmed that Windows version doesn't > flag it as a warning even with full warnings on. Indeed. *Mac* version. $ gnatmake -gnatv -gnatwa x -f gcc -c -gnatv -gnatwa x.adb GNAT 3.3 20040913 (GNAT for Mac OS X build 1650) Copyright 1992-2002 Free Software Foundation, Inc. Compiling: x.adb (source file time stamp: 2005-06-13 08:47:40) 11 lines: No errors $ ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Division by zero 2005-06-13 8:54 ` Marius Amado Alves @ 2005-06-13 17:59 ` Simon Wright 0 siblings, 0 replies; 41+ messages in thread From: Simon Wright @ 2005-06-13 17:59 UTC (permalink / raw) Marius Amado Alves <amado.alves@netcabo.pt> writes: > Indeed. *Mac* version. > > $ gnatmake -gnatv -gnatwa x -f > gcc -c -gnatv -gnatwa x.adb > > GNAT 3.3 20040913 (GNAT for Mac OS X build 1650) > Copyright 1992-2002 Free Software Foundation, Inc. > > Compiling: x.adb (source file time stamp: 2005-06-13 08:47:40) > 11 lines: No errors But with 4.0.0 built for Darwin .. both lines uncommented .. grendel:~/tmp simon$ gnatmake -c -u -f -v -gnatwaL x.adb GNATMAKE 4.0.0 Copyright 1995-2004 Free Software Foundation, Inc. gcc -c -gnatwaL x.adb x.adb:7:12: division by zero x.adb:7:12: static expression raises "Constraint_Error" x.adb:9:04: warning: unreachable code x.adb:9:13: warning: division by zero x.adb:9:13: warning: "Constraint_Error" will be raised at run time End of compilation gnatmake: "x.adb" compilation error ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2005-06-30 11:16 UTC | newest] Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-06-11 21:03 Division by zero Lurker 2005-06-12 2:00 ` David C. Hoos, Sr. 2005-06-12 3:04 ` Lurker 2005-06-12 8:39 ` Dmitry A. Kazakov 2005-06-12 9:43 ` Lurker 2005-06-12 10:36 ` Marius Amado Alves 2005-06-12 11:53 ` Dmitry A. Kazakov 2005-06-13 8:03 ` Ole-Hjalmar Kristensen 2005-06-12 13:10 ` Robert A Duff 2005-06-12 16:55 ` Jeffrey Carter 2005-06-13 3:22 ` Keith Thompson 2005-06-14 2:14 ` Jeffrey Carter 2005-06-13 8:47 ` Lurker 2005-06-14 2:19 ` Jeffrey Carter 2005-06-14 8:35 ` Keith Thompson 2005-06-13 12:19 ` Robert A Duff 2005-06-14 2:31 ` Jeffrey Carter 2005-06-14 8:21 ` Lurker 2005-06-14 20:22 ` Randy Brukardt 2005-06-28 21:22 ` Robert A Duff 2005-06-29 5:50 ` Lurker 2005-06-29 13:27 ` Robert A Duff 2005-06-29 13:54 ` Dmitry A. Kazakov 2005-06-29 16:03 ` Robert A Duff 2005-06-30 1:19 ` Lurker 2005-06-30 11:16 ` Stuart Palin 2005-06-29 13:50 ` Dmitry A. Kazakov 2005-06-29 16:07 ` Robert A Duff 2005-06-30 8:27 ` Dmitry A. Kazakov 2005-06-29 9:20 ` Lurker 2005-06-29 9:49 ` Christoph Grein 2005-06-29 10:40 ` Lurker 2005-06-29 11:04 ` Jeff Creem 2005-06-29 12:28 ` Martin Dowie 2005-06-29 13:40 ` Robert A Duff [not found] ` <5sana1pm436l6vboifijqblu0irf84afkr@4ax.com> 2005-06-12 17:38 ` Simon Wright 2005-06-12 12:21 ` Robert A Duff 2005-06-12 22:53 ` Georg Bauhaus 2005-06-13 8:34 ` Lurker 2005-06-13 8:54 ` Marius Amado Alves 2005-06-13 17:59 ` Simon Wright
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox