* Interesting effects in array renaming @ 2003-06-22 14:52 Dmitry A. Kazakov 2003-06-22 17:24 ` Jeffrey Carter 0 siblings, 1 reply; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-22 14:52 UTC (permalink / raw) ---------- test.adb with Ada.Text_IO; use Ada.Text_IO; procedure Test is type Some_Array is array (Integer range <>) of Integer; procedure Foo (X : Some_Array) is subtype Constrained is Some_Array (1..X'Length); XX : Constrained renames X; begin Put_Line ( "XX'Range:" & Integer'Image (XX'First) & ".." & Integer'Image (XX'Last) & ", Constrained'Range:" & Integer'Image (Constrained'First) & ".." & Integer'Image (Constrained'Last) ); end Foo; Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2); begin Foo (Object); end Test; ---------- test.adb Surprisingly the above produces different ranges for XX and its declared subtype. Isn't something wrong here? I would expect either 1. XX'Range = Constrained'Range and indices are shifted or 2. Raising Constraint_Error while renaming. How else could the compiler remove range checks for X : Array_Subtype ... for I in Array_Subtype'Range loop X (I) ... -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-22 14:52 Interesting effects in array renaming Dmitry A. Kazakov @ 2003-06-22 17:24 ` Jeffrey Carter 2003-06-23 8:12 ` Dmitry A. Kazakov 0 siblings, 1 reply; 20+ messages in thread From: Jeffrey Carter @ 2003-06-22 17:24 UTC (permalink / raw) Dmitry A. Kazakov wrote: > ---------- test.adb > with Ada.Text_IO; use Ada.Text_IO; > > procedure Test is > type Some_Array is array (Integer range <>) of Integer; > > procedure Foo (X : Some_Array) is > subtype Constrained is Some_Array (1..X'Length); > XX : Constrained renames X; > begin > Put_Line > ( "XX'Range:" > & Integer'Image (XX'First) > & ".." > & Integer'Image (XX'Last) > & ", Constrained'Range:" > & Integer'Image (Constrained'First) > & ".." > & Integer'Image (Constrained'Last) > ); > end Foo; > > Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2); > begin > Foo (Object); > end Test; > ---------- test.adb > > Surprisingly the above produces different ranges for XX and its declared > subtype. Isn't something wrong here? Note that you can also do subtype Constrained is Some_Array (1..X'Length-1); or subtype Constrained is Some_Array (1..3); with similar results. You can also do XX : Some_Array renames X; which perhaps demonstrates more clearly where the object's subtype comes from. -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-22 17:24 ` Jeffrey Carter @ 2003-06-23 8:12 ` Dmitry A. Kazakov 2003-06-23 10:29 ` Georg Bauhaus 2003-06-24 2:35 ` Robert I. Eachus 0 siblings, 2 replies; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-23 8:12 UTC (permalink / raw) Jeffrey Carter wrote: > Dmitry A. Kazakov wrote: >> ---------- test.adb >> with Ada.Text_IO; use Ada.Text_IO; >> >> procedure Test is >> type Some_Array is array (Integer range <>) of Integer; >> >> procedure Foo (X : Some_Array) is >> subtype Constrained is Some_Array (1..X'Length); >> XX : Constrained renames X; >> begin >> Put_Line >> ( "XX'Range:" >> & Integer'Image (XX'First) >> & ".." >> & Integer'Image (XX'Last) >> & ", Constrained'Range:" >> & Integer'Image (Constrained'First) >> & ".." >> & Integer'Image (Constrained'Last) >> ); >> end Foo; >> >> Object : Some_Array (-3..2) := (-3, -2, -1, 0, 1, 2); >> begin >> Foo (Object); >> end Test; >> ---------- test.adb >> >> Surprisingly the above produces different ranges for XX and its declared >> subtype. Isn't something wrong here? > > Note that you can also do > > subtype Constrained is Some_Array (1..X'Length-1); > > or > > subtype Constrained is Some_Array (1..3); > > with similar results. You can also do > > XX : Some_Array renames X; > > which perhaps demonstrates more clearly where the object's subtype comes > from. I see no link with subtypes. ARM clearly states: 8.5.1(6) "... any constraint implied by the subtype_mark of the object_renaming_declaration is ingored)." I.e. whatever subtype you, a programmer, might specify I, the compiler, will shamelessly ignore it! How safe! Do you really think it is OK? Consider this: X1 : Constrained := Constrained (X); X2 : Constrained renames X; What is OK here, that X1 and X2 have different constraints or that X2 is potentially invalid? I see only two alternatives: Either to add a dynamic semantics ensuring that the result of renaming is a valid object of the declared subtype. [X2 raises Constraint_Error if Constrained'Range /= X'Range] Or [painful] to require X1 and X2 be same in all cases, and thus: XX : Some_Array renames X (X'First + 1 .. X'Last); would have length different from X, so a new array dope has to be generated etc. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-23 8:12 ` Dmitry A. Kazakov @ 2003-06-23 10:29 ` Georg Bauhaus 2003-06-23 11:37 ` Dmitry A. Kazakov 2003-06-24 2:35 ` Robert I. Eachus 1 sibling, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-23 10:29 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : : "... any constraint implied by the subtype_mark of the : object_renaming_declaration is ingored)." : : I.e. whatever subtype you, a programmer, might specify I, the compiler, will : shamelessly ignore it! : : How safe! Do you really think it is OK? Consider this: [...] : I see only two alternatives: : : Either to add a dynamic semantics ensuring that the result of renaming is a : valid object of the declared subtype. [X2 raises Constraint_Error if : Constrained'Range /= X'Range] I think the compiler could warn about possibly "incompatible" constraints in a renaming declaration. Have you written to the producers of your compiler? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-23 10:29 ` Georg Bauhaus @ 2003-06-23 11:37 ` Dmitry A. Kazakov 2003-06-23 13:28 ` Georg Bauhaus 0 siblings, 1 reply; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-23 11:37 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > : > : "... any constraint implied by the subtype_mark of the > : object_renaming_declaration is ingored)." > : > : I.e. whatever subtype you, a programmer, might specify I, the compiler, > : will shamelessly ignore it! > : > : How safe! Do you really think it is OK? Consider this: > [...] > : I see only two alternatives: > : > : Either to add a dynamic semantics ensuring that the result of renaming > : is a valid object of the declared subtype. [X2 raises Constraint_Error > : if Constrained'Range /= X'Range] > > I think the compiler could warn about possibly > "incompatible" constraints in a renaming declaration. > > Have you written to the producers of your compiler? It is same in both GNAT and ObjectAda, but it is absolutely legal according to ARM. The problem is ARM itself. Which opens such a hole. What sense have our complains about buffer overruns in C/C++, in presense of this? It is also a range check optimization problem, because the compiler cannot rely on subtype information. Very bad. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-23 11:37 ` Dmitry A. Kazakov @ 2003-06-23 13:28 ` Georg Bauhaus 2003-06-24 7:35 ` Dmitry A. Kazakov 0 siblings, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-23 13:28 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : It is same in both GNAT and ObjectAda, but it is absolutely legal according : to ARM. The problem is ARM itself. Which opens such a hole. What sense have : our complains about buffer overruns in C/C++, in presense of this? It is : also a range check optimization problem, because the compiler cannot rely : on subtype information. Very bad. I don't think it is so bad, it is much more an issue of what renaming means, maybe? Most prominently, you give another name to an entity, you don't make a new entity. Why should the new name denote an entity wich has its bounds changed, despite being "just another name"? -- georg ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-23 13:28 ` Georg Bauhaus @ 2003-06-24 7:35 ` Dmitry A. Kazakov 2003-06-24 14:38 ` Georg Bauhaus 0 siblings, 1 reply; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-24 7:35 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > : It is same in both GNAT and ObjectAda, but it is absolutely legal > : according to ARM. The problem is ARM itself. Which opens such a hole. > : What sense have our complains about buffer overruns in C/C++, in > : presense of this? It is also a range check optimization problem, because > : the compiler cannot rely on subtype information. Very bad. > > I don't think it is so bad, it is much more an issue of what > renaming means, maybe? No, it is an issue of which meaning has an explicit specifying of a subtype. I would not object if the syntax were: X : renames Y; But it isn't. > Most prominently, you give another name > to an entity, you don't make a new entity. Really? To me a "view" is definitely an "entity". You probably mean that renaming should not create a new object. But it is no matter, imposing a constraint on an existing object does not change the object. It is merely a precondition. > Why should the new > name denote an entity wich has its bounds changed, despite > being "just another name"? The answer depends on whether bounds is a property of (1) a value or of (2) a type. For an unconstrained array type you have (1), for a constrained array [sub]type (2). So when you rename one to another you have a clash between (1) and (2). It has to be reconciled. In the example I gave for I in Constrained'Range loop X2 (I) := 0; end loop; may raise Constraint_Error or else corrupt memory if range checks are suppressed. It is abolutely unacceptable. To put it in one sentence: either you change bounds or you check them. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 7:35 ` Dmitry A. Kazakov @ 2003-06-24 14:38 ` Georg Bauhaus 2003-06-25 10:28 ` Dmitry A. Kazakov 0 siblings, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-24 14:38 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : Georg Bauhaus wrote: : :> I don't think it is so bad, it is much more an issue of what :> renaming means, maybe? : : No, it is an issue of which meaning has an explicit specifying of a subtype. Hm. procedure foo(a: Apple) is p: Orange renames a; may be correct, but confusing. Because, in my view a least, the programmer is violating the usual meaning of "renames". I think the bias is towards the wrong side/word if "Orange" outweighs "renames". :> Most prominently, you give another name :> to an entity, you don't make a new entity. : : Really? To me a "view" is definitely an "entity". You probably mean that : renaming should not create a new object. Yes. : But it is no matter, imposing a : constraint on an existing object does not change the object. It is merely a : precondition. Should renaming be for imposing constraints? If I rename myself as Bouwhouws, that won't change me I think, and it doesn't impose a constraint on me. That's renaming for me. It won't even change the sound of my name ;-) : for I in Constrained'Range loop : X2 (I) := 0; : end loop; : : may raise Constraint_Error or else corrupt memory if range checks are : suppressed. It is abolutely unacceptable. To put it in one sentence: either : you change bounds or you check them. But if you declare a subtype with constraints to be used in a renaming declaration, then you know the constraints. You also know the bounds of objects involved, by way of attributes. So you could make your intention more explicit by using these known quantities if you want to avoid copying. -- sb463ba ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 14:38 ` Georg Bauhaus @ 2003-06-25 10:28 ` Dmitry A. Kazakov 2003-06-25 14:23 ` Georg Bauhaus 0 siblings, 1 reply; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-25 10:28 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > : Georg Bauhaus wrote: > : > :> I don't think it is so bad, it is much more an issue of what > :> renaming means, maybe? > : > : No, it is an issue of which meaning has an explicit specifying of a > : subtype. > > Hm. > > procedure foo(a: Apple) is > p: Orange renames a; > > may be correct, but confusing. Because, in my view a least, the > programmer is violating the usual meaning of "renames". But the "usual" meaning of "renames" is: p : renames a; What meaning has Orange in renaming? Just a buzz word? Then I would propose to change the syntax to p: Orange or else renames a; It would perfecly reflect the present semantics! (:-)) What I want is: p: Orange and then renames a; > : But it is no matter, imposing a > : constraint on an existing object does not change the object. It is > : merely a precondition. > > Should renaming be for imposing constraints? > If I rename myself as Bouwhouws, that won't change me I think, > and it doesn't impose a constraint on me. It imposes a constraint on people calling you. That is the point. Consider renaming Mr.Smith to Mrs.Smith. Authorities in most contries would object, even if Mr.Smith had undergone a surgery. [Though, I could have missed the recent advances in "poltical correctness" and could be wrong] (:-)) > That's renaming for me. > It won't even change the sound of my name ;-) I give you another example. When you rename a routine: procedure Baz (A : Apple); procedure Foo (B : Apple) renames Baz; the compiler checks the specified parameter profile. According to your theory it should not. Indeed procedure Foo (B : Orange) renames Baz; by no means changes Baz. > : for I in Constrained'Range loop > : X2 (I) := 0; > : end loop; > : > : may raise Constraint_Error or else corrupt memory if range checks are > : suppressed. It is abolutely unacceptable. To put it in one sentence: > : either you change bounds or you check them. > > But if you declare a subtype with constraints to be used in a renaming > declaration, then you know the constraints. You also know the bounds of > objects involved, by way of attributes. So you could make your intention > more explicit by using these known quantities if you want to avoid > copying. Oh, that's is the very C++ ideology to me: "Wished it? Take it, idiot!" (:-)) -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-25 10:28 ` Dmitry A. Kazakov @ 2003-06-25 14:23 ` Georg Bauhaus 2003-06-25 19:00 ` Dmitry A. Kazakov 0 siblings, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-25 14:23 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : : But the "usual" meaning of "renames" is: : : p : renames a; Opening the question of why theree is a subtype mentioned in a renaming declaration. (Which I cannot answer, but I find it consistent with other declarations, which involves a subtypes name most of the times. Would you like p: constant := a; ?) :> Should renaming be for imposing constraints? :> If I rename myself as Bouwhouws, that won't change me I think, :> and it doesn't impose a constraint on me. : : It imposes a constraint on people calling you. I'd rather say it offers them the freedom to call me by that other name, which additional freedom is not a constraint. : Consider : renaming Mr.Smith to Mrs.Smith. I think this is an example of changing the type (in some humans typing scheme), or, if not, of changing the view, but _not_ the name, which is "Smith". "Smith, come here, carry that chair!" : I give you another example. When you rename a routine: : : procedure Baz (A : Apple); : procedure Foo (B : Apple) renames Baz; : : the compiler checks the specified parameter profile. According to your : theory it should not. Indeed : : procedure Foo (B : Orange) renames Baz; : : by no means changes Baz. Well, if constraints and parameter profiles should get the same treatment for reasons of consistency wrt to the criterion "checked" in renaming declarations, then, have you checked the implications of such a change? I can't do this but after reading Robert's comments, I trust this has been considered, with the result known. I still think that a compiler warning will be useful. -- georg ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-25 14:23 ` Georg Bauhaus @ 2003-06-25 19:00 ` Dmitry A. Kazakov 0 siblings, 0 replies; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-25 19:00 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > : > : But the "usual" meaning of "renames" is: > : > : p : renames a; > > Opening the question of why theree is a subtype mentioned > in a renaming declaration. (Which I cannot answer, but I > find it consistent with other declarations, which involves > a subtypes name most of the times. Would you like > p: constant := a; ?) Not as a replacement to renaming, but probably as an enhancement towards type inference. It should have other semantics than renaming. It should create a new object if "a" is not constant in the context. Consider: procedure Foo (a : in out Apple) is p : constant := a; begin Eat (a); -- What happens with p? Compare it with looking at a first glance reasonable: p : constant Apple renames a; -- p view allows no changes on a But it is a bad idea, because the contract here can be easily violated through the aliased view. Aliasing is not much compatible with invariants. So we should not pretend them existing. Thus renaming should not only check whether the renamed object has the declared subtype, but also that this cannot be changed within the scope of the created view. For example: type Vary (I : Integer) record case I is ...; subtype Fixed is Vary (0); X : Vary := ...; Y : Fixed renames X; -- Illegal, one could change X.I in Y's scope. > :> Should renaming be for imposing constraints? > :> If I rename myself as Bouwhouws, that won't change me I think, > :> and it doesn't impose a constraint on me. > : > : It imposes a constraint on people calling you. > > I'd rather say it offers them the freedom to call me by that other > name, which additional freedom is not a constraint. The constraint is that when they say "Bouwhouws", they should mean you. If "Bouwhouws" has any additional meaning it should be applicable to you, or at least not insult you. Otherwise, other people may think silly things of you. This does not impose any constraint on you. It only requires that a name fits you. So it imposes a constraint on the view. > : Consider > : renaming Mr.Smith to Mrs.Smith. > > I think this is an example of changing the type (in some humans typing > scheme), or, if not, of changing the view, but _not_ the name, > which is "Smith". "Smith, come here, carry that chair!" My Webster says that a name is "a word or combination of words by which a person or thing is reqularly known". Anyway the point was that though applying Mrs. to Mr.Smith would not change Smith, it would definitely insult him. So is it worth to try? > : I give you another example. When you rename a routine: > : > : procedure Baz (A : Apple); > : procedure Foo (B : Apple) renames Baz; > : > : the compiler checks the specified parameter profile. According to your > : theory it should not. Indeed > : > : procedure Foo (B : Orange) renames Baz; > : > : by no means changes Baz. > > Well, if constraints and parameter profiles should get the same > treatment for reasons of consistency wrt to the criterion "checked" > in renaming declarations, then, have you checked the implications > of such a change? Technically I see no problems with additional subtype check. I cannot imagine any useful code which would rely on subtype violation in case of renaming. More interesting would be to allow "violating" the constraints in a consitent way. I.e. to allow: procedure Foo (B : Orange) renames Baz; and change the semantics of p : Orange renames a; by corresponding subtype conversions: procedure Foo (B : Orange) is -- generated by the compiler begin Baz (Apple (B)); end Foo; function Get_p return Orange is -- generated by the compiler begin return Orange (a); end Get_p; procedure Set_p (p : Orange) is -- generated by the compiler begin a := Apple (p); end Set_p; But that would be much too radical to many. > I can't do this but after reading Robert's comments, > I trust this has been considered, with the result known. > > I still think that a compiler warning will be useful. Better than nothing. Unfortunately it cannot be statically checked. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-23 8:12 ` Dmitry A. Kazakov 2003-06-23 10:29 ` Georg Bauhaus @ 2003-06-24 2:35 ` Robert I. Eachus 2003-06-24 7:35 ` Dmitry A. Kazakov 1 sibling, 1 reply; 20+ messages in thread From: Robert I. Eachus @ 2003-06-24 2:35 UTC (permalink / raw) Dmitry A. Kazakov wrote: > I see no link with subtypes. ARM clearly states: 8.5.1(6) > > "... any constraint implied by the subtype_mark of the > object_renaming_declaration is ingored)." > > I.e. whatever subtype you, a programmer, might specify I, the compiler, will > shamelessly ignore it! > > How safe! Do you really think it is OK? Consider this: Let me give you a view into the the thinking behind this. Renaming is just another way to create aliasing in Ada. We couldn't do away with the aliasing provided by, for example, subprogram parameters, and all aliasing has the potential to create havoc. The consensus was that Ada allows programmers to avoid aliasing, but it doesn't require programmers do so. Why? Because the havoc that can occur is only in the mind of the programmer. There are a lot of validation tests that use aliasing to accomplish a particular purpose. But the results of all those tests (at least in a conforming complier) is predictable. The same applies in this case. I often use aliasing "tricks" to make writing string handling code easier. If a subprogam has a parameter say S: in String, you don't know that the S'First is 1. But if you write: subtype S_String is String(1..S'Length); My_S: S_String renames S; now you can assume that the lower bound is 1. But notice a detail here. A renaming takes a subtype_mark rather than a subtype_indication. In general when only a subtype mark is allowed in Ada, it indicates that what matters is the TYPE indicated by the subtype_mark. In practice, I tend to write My_S: constant String(1..S'Length) := S; if that is what I want, because it also eliminates the possibility that S is passed by reference, and some other task modifies it. But in general the question is how much (code and time) can I afford to spend making my library routine bulletproof. Ada allows me to make that sort of tradeoff. Also, it would seem to be a nice idea to either require that the constraints implied by subtype_mark in a renaming declaration be checked, or that the subtype_mark be a first named subtype. The first doesn't work, because we already know that aliasing is going on. Checking the value at one point in time provides no real additional safety. As for requiring the name be a first named subtype, I think that was in there at one point. But it turned out to have problems, often the only subtype_mark available to you is an alias! For example, renamings inside generics. So this turns out to be one of those cases where Ada doesn't mandate good sense on the part of the programmer, and spends a lot of words covering all the different ways you MAY shoot yourself in the foot. But as long as the semantics are defined, as I said way back at the top, the intended effect is the one in the programmers mind. If that is not the required semantic effect, the programmer will be surprised. RM 8.5.1(6) is pretty clear on what the programmer should expect: "An object_renaming_declaration declares a new view of the renamed object..." If you expect a value conversion, sorry about that, what you get is a view conversion. If you don't understand the difference between a value conversion and a view conversion, go reread RM 4.6. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 2:35 ` Robert I. Eachus @ 2003-06-24 7:35 ` Dmitry A. Kazakov 2003-06-24 10:08 ` Lutz Donnerhacke 2003-06-24 11:53 ` Georg Bauhaus 0 siblings, 2 replies; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-24 7:35 UTC (permalink / raw) Robert I. Eachus wrote: > Dmitry A. Kazakov wrote: > >> I see no link with subtypes. ARM clearly states: 8.5.1(6) >> >> "... any constraint implied by the subtype_mark of the >> object_renaming_declaration is ingored)." >> >> I.e. whatever subtype you, a programmer, might specify I, the compiler, >> will shamelessly ignore it! >> >> How safe! Do you really think it is OK? Consider this: > > Let me give you a view into the the thinking behind this. Renaming is > just another way to create aliasing in Ada. We couldn't do away with > the aliasing provided by, for example, subprogram parameters, and all > aliasing has the potential to create havoc. The consensus was that Ada > allows programmers to avoid aliasing, but it doesn't require programmers > do so. > > Why? Because the havoc that can occur is only in the mind of the > programmer. There are a lot of validation tests that use aliasing to > accomplish a particular purpose. But the results of all those tests (at > least in a conforming complier) is predictable. > > The same applies in this case. I often use aliasing "tricks" to make > writing string handling code easier. If a subprogam has a parameter say > S: in String, you don't know that the S'First is 1. But if you write: > subtype S_String is String(1..S'Length); My_S: S_String renames S; now > you can assume that the lower bound is 1. (?) You mean that I cannot, because My_S'First = S'First. > But notice a detail here. A > renaming takes a subtype_mark rather than a subtype_indication. In > general when only a subtype mark is allowed in Ada, it indicates that > what matters is the TYPE indicated by the subtype_mark. Oh yes, ARM consistently states inconsistent things! (:-)) > In practice, I tend to write My_S: constant String(1..S'Length) := S; if > that is what I want, because it also eliminates the possibility that S > is passed by reference, I usually declare a nested subprogram which takes S_String and does the things. > and some other task modifies it. I would not rely on it. > But in general > the question is how much (code and time) can I afford to spend making my > library routine bulletproof. Ada allows me to make that sort of > tradeoff. > > Also, it would seem to be a nice idea to either require that the > constraints implied by subtype_mark in a renaming declaration be > checked, or that the subtype_mark be a first named subtype. The first > doesn't work, because we already know that aliasing is going on. > Checking the value at one point in time provides no real additional > safety. It povides additional safety for the reader of a program. [Isn't a goal Ada design?] It would allow to omit range checks many cases like: procedure Sum (L : in out Vector; R : Vector) is subtype Of_L is Vector (L'Range); RR : Of_L renames R; -- Checked here begin for I in L'Range loop L (I) := L (I) + RR (I); -- No range check needed Far clearer than the trick with a nested subprogram: procedure Sum (L : in out Vector; R : Vector) is subtype Of_L is Vector (L'Range); procedure Do_Sum (LL : in out Of_L; RR : Of_L) is begin for I in Of_L'Range loop LL (I) := LL (I) + RR (I); -- No range check needed end loop; end Do_Sum; begin Do_Sum (L, R); Presently Ada has no easy way to help the compiler in optimizing programs like above. Perhaps it will be achieved with preconditions if they at last appear in Ada. But even then I would expect: X : S renames Y; be equivalent to ensure Y in S; X : S renames Y; > As for requiring the name be a first named subtype, I think > that was in there at one point. But it turned out to have problems, > often the only subtype_mark available to you is an alias! For example, > renamings inside generics. So this turns out to be one of those cases > where Ada doesn't mandate good sense on the part of the programmer, and > spends a lot of words covering all the different ways you MAY shoot > yourself in the foot. > > But as long as the semantics are defined, as I said way back at the top, > the intended effect is the one in the programmers mind. If that is not > the required semantic effect, the programmer will be surprised. RM > 8.5.1(6) is pretty clear on what the programmer should expect: "An > object_renaming_declaration declares a new view of the renamed object..." That the new view is wellcome to be inconsistent does not follow from that. It is written pair lines below. BTW, for tagged types it is different and semantically consistent: procedure Foo (X : Base'Class) is XX : Derived renames X; -- Illegal XX : Derived renames Derived (X); -- Legal and *CHECKED* > If you expect a value conversion, sorry about that, what you get is a > view conversion. If you don't understand the difference between a value > conversion and a view conversion, go reread RM 4.6. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 7:35 ` Dmitry A. Kazakov @ 2003-06-24 10:08 ` Lutz Donnerhacke 2003-06-24 11:53 ` Georg Bauhaus 1 sibling, 0 replies; 20+ messages in thread From: Lutz Donnerhacke @ 2003-06-24 10:08 UTC (permalink / raw) * Dmitry A. Kazakov wrote: > It povides additional safety for the reader of a program. [Isn't a goal Ada > design?] It would allow to omit range checks many cases like: > > procedure Sum (L : in out Vector; R : Vector) is > subtype Of_L is Vector (L'Range); > RR : Of_L renames R; -- Checked here > begin > for I in L'Range loop > L (I) := L (I) + RR (I); -- No range check needed Currently this is not the case: $ cat > test.adb <<END procedure Test is type Vector is array (Integer range <>) of Integer; procedure Sum (L : in out Vector; R : Vector) is subtype Of_L is Vector (L'Range); RR : Of_L renames R; -- Checked here begin for I in L'Range loop L (I) := L (I) + RR (I); -- No range check needed end loop; end Sum; a : Vector := (4 .. 10 => 4); b : Vector := (1, 2, 3); begin Sum(a, b); end Test; END $ gnatmake test gcc -c test.adb gnatbind -x test.ali gnatlink test.ali gnatlink: warning: executable name "test" may conflict with shell command $ ./test raised CONSTRAINT_ERROR : test.adb:10 $ sed -n 10p test.adb L (I) := L (I) + RR (I); -- No range check needed $ _ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 7:35 ` Dmitry A. Kazakov 2003-06-24 10:08 ` Lutz Donnerhacke @ 2003-06-24 11:53 ` Georg Bauhaus 2003-06-24 12:48 ` Dmitry A. Kazakov 1 sibling, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-24 11:53 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : That the new view is wellcome to be inconsistent does not follow from that. : It is written pair lines below. BTW, for tagged types it is different and : semantically consistent: : : procedure Foo (X : Base'Class) is : XX : Derived renames X; -- Illegal : XX : Derived renames Derived (X); -- Legal and *CHECKED* I'm not sure, considering procedure Foo (X : in out Varying'Class) is subtype Nono is Changeant (false); X1 : Changeant renames X; -- Illegal X2 : Nono renames Changeant(X); -- Legal and *CHECKED* begin X2.messy := 2 * X2.messy; -- constraint_error when discriminant is true end Foo; where package Derivs is type Varying (special: Boolean) is tagged record comp: Natural; end record; type Changeant (very_special: Boolean) is new Varying(very_special) with record case very_special is when true => another: Boolean; when false => messy: Integer; end case; end record; end Derivs; -- Georg ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 11:53 ` Georg Bauhaus @ 2003-06-24 12:48 ` Dmitry A. Kazakov 2003-06-26 2:54 ` Randy Brukardt 0 siblings, 1 reply; 20+ messages in thread From: Dmitry A. Kazakov @ 2003-06-24 12:48 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > : That the new view is wellcome to be inconsistent does not follow from > : that. It is written pair lines below. BTW, for tagged types it is > : different and semantically consistent: > : > : procedure Foo (X : Base'Class) is > : XX : Derived renames X; -- Illegal > : XX : Derived renames Derived (X); -- Legal and *CHECKED* > > I'm not sure, considering > > procedure Foo (X : in out Varying'Class) is > subtype Nono is Changeant (false); > X1 : Changeant renames X; -- Illegal > X2 : Nono renames Changeant(X); -- Legal and *CHECKED* You could make it even more scandalous: X2 : Nono renames Nono(X); -- !!!No discriminant checks!!! > begin > X2.messy := 2 * X2.messy; > -- constraint_error when discriminant is true > end Foo; > > where > package Derivs is > > type Varying (special: Boolean) > is > tagged record > comp: Natural; > end record; > > type Changeant (very_special: Boolean) > is > new Varying(very_special) with > record > case very_special is > when true => > another: Boolean; > when false => > messy: Integer; > end case; > end record; > end Derivs; Clarification: I meant tags, not discriminants (of possibly tagged types). What happens in your example, is the following. Nono has two constraints: 1. The discriminant very_special => False 2. The tag => Changeant'Tag (viewed as a constraint for any of the classes: Varying'Class, Changeant'Class) When you rename X, the constraint 2 is checked. The constraint 1 is silently ignored as ARM requires. Here we are. Now, convince me that it is GOOD. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-24 12:48 ` Dmitry A. Kazakov @ 2003-06-26 2:54 ` Randy Brukardt 2003-06-26 6:27 ` Vinzent Hoefler 0 siblings, 1 reply; 20+ messages in thread From: Randy Brukardt @ 2003-06-26 2:54 UTC (permalink / raw) Dmitry A. Kazakov wrote in message ... >Here we are. Now, convince me that it is GOOD. I doubt anyone could do that, for the simple reason that you're right. But there are a number of things about Ada that are wrong (the inability to use "in out" parameters on functions is the most obvious to me), but they're not going to be changed because of compatibility and/or political reasons. That's the nature of the beast -- you'll never get everything you want (or even close to it) -- and in total that might be a good thing. In the case of the renames, that would substantially change the semantics of existing programs, both for renames themselves and for generic in out parameters (which are defined in terms of renames). It would be too much of a change - a lot of existing code would fail. I find cases where the political process prevents needed fixes (like the 'in out' parameters on functions issue) much more annoying. At least in the cases of compatibility, you can convince yourself that there really is no choice... Randy. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-26 2:54 ` Randy Brukardt @ 2003-06-26 6:27 ` Vinzent Hoefler 2003-06-26 12:44 ` Georg Bauhaus 0 siblings, 1 reply; 20+ messages in thread From: Vinzent Hoefler @ 2003-06-26 6:27 UTC (permalink / raw) Randy Brukardt wrote: >But there are a number of things about Ada that are wrong (the inability >to use "in out" parameters on functions is the most obvious to me), In fact the idea that a function shall have no (or at least very limited) side effects is a quite good one. Well, you still can use global variables or access-Parameters to circumvent this restriction, so perhaps one can consider it as rather inconsequential, but wrong? No, I don't think so. Vinzent. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-26 6:27 ` Vinzent Hoefler @ 2003-06-26 12:44 ` Georg Bauhaus 2003-06-26 13:01 ` Vinzent Hoefler 0 siblings, 1 reply; 20+ messages in thread From: Georg Bauhaus @ 2003-06-26 12:44 UTC (permalink / raw) Vinzent Hoefler <ada.rocks@jlfencey.com> wrote: : Randy Brukardt wrote: : :>But there are a number of things about Ada that are wrong (the inability :>to use "in out" parameters on functions is the most obvious to me), : : In fact the idea that a function shall have no (or at least very pure : limited) side effects is a quite good one. Image the name of the beast wasn't function. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Interesting effects in array renaming 2003-06-26 12:44 ` Georg Bauhaus @ 2003-06-26 13:01 ` Vinzent Hoefler 0 siblings, 0 replies; 20+ messages in thread From: Vinzent Hoefler @ 2003-06-26 13:01 UTC (permalink / raw) Georg Bauhaus wrote: >Vinzent Hoefler <ada.rocks@jlfencey.com> wrote: >: Randy Brukardt wrote: >: >:>But there are a number of things about Ada that are wrong (the inability >:>to use "in out" parameters on functions is the most obvious to me), >: >: In fact the idea that a function shall have no (or at least very > pure >: limited) side effects is a quite good one. > >Image the name of the beast wasn't function. Well, I was thinking of VHDL and there exists the concept of pure and impure functions. "pure" says, regardless of what happens, this function will *always* return the same value for the same parameter set with which it is called, but the "impure" function might read some signal, so its return value might be different from the previous even when called with the same parameters. So i.e. SPARK's functions that should be free of side effects, are really the equivalent to VHDL's _im_pure function like this one: |impure function Check_Signal (Signal : Std_Logic) return Std_Logic is |begin | return Global_State xor Signal; |end Check_Signal; So, no. A pure function (in a more mathematical sense) was not what I was talking about. Impure functions look ok for me, but they still shouldn't be able to change their parameters or (more generally) the state of the system. Vinzent. -- Parents strongly cautioned -- this posting is intended for mature audiences over 18. It may contain some material that many parents would not find suitable for children and may include intense violence, sexual situations, coarse language and suggestive dialogue. ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2003-06-26 13:01 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-06-22 14:52 Interesting effects in array renaming Dmitry A. Kazakov 2003-06-22 17:24 ` Jeffrey Carter 2003-06-23 8:12 ` Dmitry A. Kazakov 2003-06-23 10:29 ` Georg Bauhaus 2003-06-23 11:37 ` Dmitry A. Kazakov 2003-06-23 13:28 ` Georg Bauhaus 2003-06-24 7:35 ` Dmitry A. Kazakov 2003-06-24 14:38 ` Georg Bauhaus 2003-06-25 10:28 ` Dmitry A. Kazakov 2003-06-25 14:23 ` Georg Bauhaus 2003-06-25 19:00 ` Dmitry A. Kazakov 2003-06-24 2:35 ` Robert I. Eachus 2003-06-24 7:35 ` Dmitry A. Kazakov 2003-06-24 10:08 ` Lutz Donnerhacke 2003-06-24 11:53 ` Georg Bauhaus 2003-06-24 12:48 ` Dmitry A. Kazakov 2003-06-26 2:54 ` Randy Brukardt 2003-06-26 6:27 ` Vinzent Hoefler 2003-06-26 12:44 ` Georg Bauhaus 2003-06-26 13:01 ` Vinzent Hoefler
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox