* worrying behaviour @ 2008-05-02 15:26 echancrure 2008-05-02 15:54 ` Adam Beneschan 0 siblings, 1 reply; 6+ messages in thread From: echancrure @ 2008-05-02 15:26 UTC (permalink / raw) After the discussion on static expressions etc. I came up against this problem which I thought was initially related to it but probably not. let's say I have: with Ada.Text_IO; use Ada.Text_IO; with ints; procedure static is function "-"(L, R : ints.My_Int) return ints.My_int renames ints."-"; function "-"(L : ints.My_Int) return ints.My_int renames ints."-"; Y : constant ints.My_int := -1; Z : constant ints.My_int := 1-1; begin Put_Line (ints.My_Int'Image (Y) & ints.My_Int'Image (Z)); end static; and package ints is type My_Int is range -100..100; function "-" (L, R : My_Int) return My_int; end ints; package body ints is function "-" (L, R : My_Int) return My_Int is begin return 42; end "-"; end ints; So basically, I have forgotten to define unary "-" in the the ints package. gnat does not complain and the .exe returns '-1 42' as would be expected without the unary - rename. Here however I have renamed the unary - to something that does not exist. Surely an error should be generated here. Otherwise this is very dangerous behaviour. Please enlight me. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: worrying behaviour 2008-05-02 15:26 worrying behaviour echancrure @ 2008-05-02 15:54 ` Adam Beneschan 2008-05-02 17:41 ` echancrure 2008-05-03 1:15 ` Randy Brukardt 0 siblings, 2 replies; 6+ messages in thread From: Adam Beneschan @ 2008-05-02 15:54 UTC (permalink / raw) On May 2, 8:26 am, echancr...@gmail.com wrote: > After the discussion on static expressions etc. > > I came up against this problem which I thought was initially related > to it but probably not. > > let's say I have: > > with Ada.Text_IO; use Ada.Text_IO; > with ints; > procedure static is > function "-"(L, R : ints.My_Int) return ints.My_int renames > ints."-"; > function "-"(L : ints.My_Int) return ints.My_int renames ints."-"; > Y : constant ints.My_int := -1; > Z : constant ints.My_int := 1-1; > begin > Put_Line (ints.My_Int'Image (Y) & ints.My_Int'Image (Z)); > end static; > > and > > package ints > is > type My_Int is range -100..100; > function "-" (L, R : My_Int) return My_int; > end ints; > > package body ints > is > function "-" (L, R : My_Int) return My_Int > is > begin > return 42; > end "-"; > end ints; > > So basically, I have forgotten to define unary "-" in the the ints > package. It's automatically defined for all integer types (such as My_Int), as are unary "+" and binary "+", "-", "*", "/", etc. In the Ints package, you've overridden the binary "-", but the other predefined operations are not affected and are still visible. So unary "-" does exist. I'm not sure that there's a good solution in Ada. If you really wanted to make sure that the only operators available for My_Int are the ones that you remembered to override, you could declare My_Int private, but then you'd lose the ability to have numeric literals for that type (in other packages). I suppose that having some sort of language construct that says "kill all predefined operators for a type" would be useful in your case. On the other hand, your example is obviously not a real-world case, and I'm having trouble envisioning a case where this would be an issue. In a real-life situation, either it would be OK to make the type a private type, or (if the type really were an integer type) there wouldn't be any problem with allowing the predefined operators to exist. (Especially unary "-". I know that "*" and "/" can cause headaches for types that represent measurements, but addition and comparison operations don't have this issue.) Perhaps someone could give an example of a situation where a feature that prevents predefined integer operations from being defined would be useful, but I can't think of one offhand. Are you working on a real-life project where this is a real danger, or are you simply trying to test your understanding of the language? > gnat does not complain and the .exe returns '-1 42' as would be > expected without the unary - rename. > > Here however I have renamed the unary - to something that does not > exist. It does exist, as I've explained. > Surely an error should be generated here. Otherwise this is very > dangerous behaviour. There are cases where compilers sometimes generate warnings, because while they are legal Ada there is a very high probability that the programmer did something wrong. An example would be defining a "+" function that renames a "*" defined in another package. However, defining a unary "-" that renames another unary "-" is a common idiom (and was even moreso before USE TYPE was added to Ada 95). I don't see anything in this code that a compiler could reasonably warn about, although perhaps others may have different opinions about that. -- Adam ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: worrying behaviour 2008-05-02 15:54 ` Adam Beneschan @ 2008-05-02 17:41 ` echancrure 2008-05-02 18:31 ` Adam Beneschan 2008-05-03 1:15 ` Randy Brukardt 1 sibling, 1 reply; 6+ messages in thread From: echancrure @ 2008-05-02 17:41 UTC (permalink / raw) On May 2, 4:54 pm, Adam Beneschan <a...@irvine.com> wrote: > On May 2, 8:26 am, echancr...@gmail.com wrote: > > > > > After the discussion on static expressions etc. > > > I came up against this problem which I thought was initially related > > to it but probably not. > > > let's say I have: > > > with Ada.Text_IO; use Ada.Text_IO; > > with ints; > > procedure static is > > function "-"(L, R : ints.My_Int) return ints.My_int renames > > ints."-"; > > function "-"(L : ints.My_Int) return ints.My_int renames ints."-"; > > Y : constant ints.My_int := -1; > > Z : constant ints.My_int := 1-1; > > begin > > Put_Line (ints.My_Int'Image (Y) & ints.My_Int'Image (Z)); > > end static; > > > and > > > package ints > > is > > type My_Int is range -100..100; > > function "-" (L, R : My_Int) return My_int; > > end ints; > > > package body ints > > is > > function "-" (L, R : My_Int) return My_Int > > is > > begin > > return 42; > > end "-"; > > end ints; > > > So basically, I have forgotten to define unary "-" in the the ints > > package. > > It's automatically defined for all integer types (such as My_Int), as > are unary "+" and binary "+", "-", "*", "/", etc. In the Ints > package, you've overridden the binary "-", but the other predefined > operations are not affected and are still visible. So unary "-" does > exist. > > I'm not sure that there's a good solution in Ada. If you really > wanted to make sure that the only operators available for My_Int are > the ones that you remembered to override, you could declare My_Int > private, but then you'd lose the ability to have numeric literals for > that type (in other packages). I suppose that having some sort of > language construct that says "kill all predefined operators for a > type" would be useful in your case. > > On the other hand, your example is obviously not a real-world case, > and I'm having trouble envisioning a case where this would be an > issue. In a real-life situation, either it would be OK to make the > type a private type, or (if the type really were an integer type) > there wouldn't be any problem with allowing the predefined operators > to exist. (Especially unary "-". I know that "*" and "/" can cause > headaches for types that represent measurements, but addition and > comparison operations don't have this issue.) Perhaps someone could > give an example of a situation where a feature that prevents > predefined integer operations from being defined would be useful, but > I can't think of one offhand. > > Are you working on a real-life project where this is a real danger, or > are you simply trying to test your understanding of the language? > > > gnat does not complain and the .exe returns '-1 42' as would be > > expected without the unary - rename. > > > Here however I have renamed the unary - to something that does not > > exist. > > It does exist, as I've explained. > > > Surely an error should be generated here. Otherwise this is very > > dangerous behaviour. > > There are cases where compilers sometimes generate warnings, because > while they are legal Ada there is a very high probability that the > programmer did something wrong. An example would be defining a "+" > function that renames a "*" defined in another package. > > However, defining a unary "-" that renames another unary "-" is a > common idiom (and was even moreso before USE TYPE was added to Ada > 95). I don't see anything in this code that a compiler could > reasonably warn about, although perhaps others may have different > opinions about that. > > -- Adam Thanks Adam for your comprehensive answer. I know there is no error here, I just thought that if you explicitly bother to provide a renaming operator declaration it would be reasonable for the compiler to expect an explicit definition for it... Of course declaring the type private would highlight the problem but ... are you really sure that in the real world those mistakes are not made? (would be pretty hard to detect and would probably only be revealed on boundary cases) After all what is the point of renaming an operator and not provide an actual body for it but the default one? Does it not deserve a warning? Is this allowed in Spark (I think it is but I have no Spark checker)? regards, chris ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: worrying behaviour 2008-05-02 17:41 ` echancrure @ 2008-05-02 18:31 ` Adam Beneschan 0 siblings, 0 replies; 6+ messages in thread From: Adam Beneschan @ 2008-05-02 18:31 UTC (permalink / raw) On May 2, 10:41 am, echancr...@gmail.com wrote: > Thanks Adam for your comprehensive answer. > I know there is no error here, I just thought that if you explicitly > bother to provide a renaming operator declaration it would be > reasonable for the compiler to expect an explicit definition for it... Not at all; I think it's quite common to rename implicitly declared operators. > Of course declaring the type private would highlight the problem > but ... are you really sure that in the real world those mistakes are > not made? (would be pretty hard to detect and would probably only be > revealed on boundary cases) They may well be made. But a compiler can't reasonably catch all mistakes. > After all what is the point of renaming an operator and not provide an > actual body for it but the default one? To be able to use the operator without having to USE the package. USE TYPE makes this less necessary, but there's a lot of legacy code out there written before Ada 95. Also, there may be reasons why USE TYPE is undesirable in particular situations, but I'm not sure what they are... perhaps others could elaborate if there are. Actually, now that I think of it, your question doesn't make that much sense. Other than the reason I've alluded to (i.e. making an operator visible), I don't see any point to renaming an operator that *does* have an actual body for it---I don't see why the explicitness or implicitness of the operator's definition makes any difference. (There are cases where you need a rename to avoid an ambiguity, but in those cases you wouldn't be renaming an operator to the same operator string, so I'm assuming that case isn't relevant to this discussion.) -- Adam ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: worrying behaviour 2008-05-02 15:54 ` Adam Beneschan 2008-05-02 17:41 ` echancrure @ 2008-05-03 1:15 ` Randy Brukardt 2008-05-03 2:04 ` Adam Beneschan 1 sibling, 1 reply; 6+ messages in thread From: Randy Brukardt @ 2008-05-03 1:15 UTC (permalink / raw) "Adam Beneschan" <adam@irvine.com> wrote in message news:ea92a206-7617-4968-90c2-31fcc30d5e40@r9g2000prd.googlegroups.com... ... > I'm not sure that there's a good solution in Ada. If you really > wanted to make sure that the only operators available for My_Int are > the ones that you remembered to override, you could declare My_Int > private, but then you'd lose the ability to have numeric literals for > that type (in other packages). I suppose that having some sort of > language construct that says "kill all predefined operators for a > type" would be useful in your case. That's not available, but you can kill them one-by-one by declaring them abstract: function "-" (R : My_Int) return My_int is abstract; makes "-" effectively undefined for type My_Int. (This is new in Ada 2005, in Ada 95 it is defined and uncallable -- the difference is that it might conflict with some user-defined routine and cause trouble.) Randy. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: worrying behaviour 2008-05-03 1:15 ` Randy Brukardt @ 2008-05-03 2:04 ` Adam Beneschan 0 siblings, 0 replies; 6+ messages in thread From: Adam Beneschan @ 2008-05-03 2:04 UTC (permalink / raw) On May 2, 6:15 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > "Adam Beneschan" <a...@irvine.com> wrote in message > > news:ea92a206-7617-4968-90c2-31fcc30d5e40@r9g2000prd.googlegroups.com... > ... > > > I'm not sure that there's a good solution in Ada. If you really > > wanted to make sure that the only operators available for My_Int are > > the ones that you remembered to override, you could declare My_Int > > private, but then you'd lose the ability to have numeric literals for > > that type (in other packages). I suppose that having some sort of > > language construct that says "kill all predefined operators for a > > type" would be useful in your case. > > That's not available, but you can kill them one-by-one by declaring them > abstract: > > function "-" (R : My_Int) return My_int is abstract; > > makes "-" effectively undefined for type My_Int. (This is new in Ada 2005, > in Ada 95 it is defined and uncallable -- the difference is that it might > conflict with some user-defined routine and cause trouble.) Right. The reason I didn't mention this was because the original problem appeared to be caused (perhaps hypothetically) by someone forgetting to override an operator in the package; and if they forgot to override it they wouldn't remember to override it with an abstract function either. That's why one construct to get rid of all the predefined functions would work better here, although I'm still not convinced that there's a real need for it. -- Adam ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2008-05-03 2:04 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-05-02 15:26 worrying behaviour echancrure 2008-05-02 15:54 ` Adam Beneschan 2008-05-02 17:41 ` echancrure 2008-05-02 18:31 ` Adam Beneschan 2008-05-03 1:15 ` Randy Brukardt 2008-05-03 2:04 ` Adam Beneschan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox