comp.lang.ada
 help / color / mirror / Atom feed
* Is this legal ?
@ 1991-11-08 20:58 Boris Pelakh
  0 siblings, 0 replies; 9+ messages in thread
From: Boris Pelakh @ 1991-11-08 20:58 UTC (permalink / raw)


The following procedure produces a warning at compile time saying that
the declaration of NULL_LINE is exceeding the storage limit of the 
implementation. At runtime, I get a storage error. It looks like the 
unconstrined declare is causing an attempt to allocate a STRING(1..MAX_INT),
even though I would expect it to only declare a STRING(1..10). The RM
does not explain this particular case. Any ideas ?

--------------

procedure BROKE is
   type VAR_LINE(LENGTH : INTEGER := 10) is
      record
             IMAGE : STRING(1..LENGTH);
      end record;
   NULL_LINE : VAR_LINE;
begin
    null;
end BROKE;

--------------

--
Boris Pelakh            Development Software Test       pelakh@convex.com
"You can see me tonight with an illegal smile. Doesn't cost very much, but
 it lasts a long while ..."		- John Prine, "Illegal Smile"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal ?
@ 1991-11-09  3:20 Robert I. Eachus
  0 siblings, 0 replies; 9+ messages in thread
From: Robert I. Eachus @ 1991-11-09  3:20 UTC (permalink / raw)


In article <1991Nov08.205832.26958@convex.com> pelakh@convex.com (Boris Pelakh)
 writes:

   The following procedure produces a warning at compile time saying that
   the declaration of NULL_LINE is exceeding the storage limit of the 
   implementation. At runtime, I get a storage error. It looks like the 
   unconstrined declare is causing an attempt to allocate a STRING(1..MAX_INT),
   even though I would expect it to only declare a STRING(1..10). The RM
   does not explain this particular case. Any ideas ?

   Why would you expect it to allocate space for only 10 characters?
The object NULL_LINE can be used to store a STRING value of any size,
since the discriminant has a default and is of type INTEGER.  There
are two standard implementations of such records, the `hidden pointer'
version which stores the actual values on the heap, and an allocate
the maximum strategy.  (Some compilers implement both, with a size at
which they cut over.)

   If you want to store reasonable length lines in a portable way,
try:

   procedure NOT_BROKE is
      subtype LINE_LENGTH is INTEGER range 0..1024;
      type VAR_LINE(LENGTH : LINE_LENGTH := 10) is
	 record
		IMAGE : STRING(1..LENGTH);
	 end record;
      NULL_LINE : VAR_LINE;
   begin
       null;
   end BROKE;

--

					Robert I. Eachus

with STANDARD_DISCLAIMER;
use  STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal ?
@ 1991-11-09 18:02 Bud Bach
  0 siblings, 0 replies; 9+ messages in thread
From: Bud Bach @ 1991-11-09 18:02 UTC (permalink / raw)


pelakh@convex.com (Boris Pelakh) writes:

> Blah, Blah, Blah...

>procedure BROKE is
>   type VAR_LINE(LENGTH : INTEGER := 10) is
>      record
>             IMAGE : STRING(1..LENGTH);
>      end record;
>   NULL_LINE : VAR_LINE;
>begin
>    null;
>end BROKE;

This is sort of a FAQ.

It has been fairly common for implementations to allocate the maximum
possible space in this situation.

Is it possible that you could constrain the length to something smaller
than "Integer"?

    procedure Common_Problem is

      subtype Reasonable_Length is Integer range 1..255;

      type Var_Line (Length : Reasonable_Length := 10) is
	record
	  Image : String (1 .. Length);
	end record;

    begin
      null;
    end Common_Problem;

Of course, knowing that the compiler will allocate "Reasonable_Length"
characters for each object of type "Var_Line", you might want to choose a
different representation.  Representations for strings always seem highly
application dependent.  There has been some recent discussion about string
representations in comp.compilers that you may want to reference.

Good luck,  -- Bud



-- 
Bud Bach - Consultant				c/o Motorola
708 632-3449					Cellular Infrastructure Group
...!uunet!motcid!bachww or			1501 W. Shure Drive, MS-1235
bachww%motcid@uunet.uu.net			Arlington Heights, IL  60004

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Is this legal?
@ 2021-10-16 19:00 Simon Belmont
  2021-10-17  8:35 ` Gautier write-only address
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Simon Belmont @ 2021-10-16 19:00 UTC (permalink / raw)


I'm trying to learn the 2012 changes to accessibility rules, e.g. aliased parameters, additional dynamics checks, and some eliminated unnecessary typecasts.  But I am also aware of the....fluid nature of GNATs correctness of implementing them, and the following situation seems dubious.  In particular, when 'current' is an anonymous access type, it compiles without issue, but not when it's a named access type (or when explicitly converted to one).  Does anyone know off hand which is the correct behavior?

Thanks
-sb

procedure Main is

   subtype str5 is string(1..5);
   type s5_ptr is access all str5;
      
   type T is
      record
         current : access str5; 
         --current : s5_ptr; -- "aliased actual has wrong accessibility"
         foo : aliased str5;
      end record;
      
   function F (y : aliased in out str5) return access str5 is
   begin
      return y'Access;
   end F;
   
   
   procedure P (x : in out T) is
   begin
      x.current := F(x.foo);
   end P;
         
  o : T := (current => null,  foo => "Hello");
   
begin
   P(o);
end Main;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal?
  2021-10-16 19:00 Is this legal? Simon Belmont
@ 2021-10-17  8:35 ` Gautier write-only address
  2021-10-17  8:41 ` AdaMagica
  2021-10-19  3:50 ` Randy Brukardt
  2 siblings, 0 replies; 9+ messages in thread
From: Gautier write-only address @ 2021-10-17  8:35 UTC (permalink / raw)


For information, ObjectAda v.10.2 accepts both variants (in Ada 2012 mode).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal?
  2021-10-16 19:00 Is this legal? Simon Belmont
  2021-10-17  8:35 ` Gautier write-only address
@ 2021-10-17  8:41 ` AdaMagica
  2021-10-17 18:31   ` Simon Belmont
  2021-10-19  3:50 ` Randy Brukardt
  2 siblings, 1 reply; 9+ messages in thread
From: AdaMagica @ 2021-10-17  8:41 UTC (permalink / raw)


> procedure Main is 
> 
> subtype str5 is string(1..5); 
> type s5_ptr is access all str5; 

Ptr: s5_ptr;

> type T is 
> record 
> --current : access str5; 
> current : s5_ptr; -- "aliased actual has wrong accessibility" 
> foo : aliased str5; 
> end record; 

The accessibility rules are far too complicated and unreadable (I'm not about trying to grock them), but the component current has a type that has a lifetime as long as Main. Your object o may be declared in an inner scope with less lifetime. Thus the assignment must be illegal.

begin
  declare
    o : T := (Acurrent => null, --Ncurrent => null,
             foo => "Hello");
  begin
    P (o);
    --Ptr := o.Ncurrent;  -- global point to disappearing object
    Ptr := o.Acurrent;  -- global point to disappearing object
  end;
  put_line(Ptr.all);  -- prints Hello
end Main;

But it occurs to me that GNAT CE 2021 has a problem here. (Comment out all occurrences of Ncurrent.)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal?
  2021-10-17  8:41 ` AdaMagica
@ 2021-10-17 18:31   ` Simon Belmont
  2021-10-18 10:50     ` AdaMagica
  0 siblings, 1 reply; 9+ messages in thread
From: Simon Belmont @ 2021-10-17 18:31 UTC (permalink / raw)


On Sunday, October 17, 2021 at 4:41:17 AM UTC-4, AdaMagica wrote:

> The accessibility rules are far too complicated and unreadable (I'm not about trying to grock them), but the component current has a type that has a lifetime as long as Main. Your object o may be declared in an inner scope with less lifetime. Thus the assignment must be illegal. 

I only ask because there are two rules, one that says the scope of the object must be *statically* deeper than the return type of the function to be legal, but then another similar one down the page that says a runtime check is made to ensure it (which begs the question of why the runtime check is needed if it must be done statically).  Normally things like that are for edge cases with anonymous access types, so it's not immediately obvious (to me, at least) if GNAT is blowing the static check or the dynamic check (Or both?  Or neither?)

6.4.1~6.3/3
  In a function call, the accessibility level of the actual object for each explicitly aliased parameter shall not be statically deeper than the accessibility level of the master of the call (see 3.10.2).

6.4.1~15.1/3
In a function call, for each explicitly aliased parameter, a check is made that the accessibility level of the master of the actual object is not deeper than that of the master of the call (see 3.10.2).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal?
  2021-10-17 18:31   ` Simon Belmont
@ 2021-10-18 10:50     ` AdaMagica
  0 siblings, 0 replies; 9+ messages in thread
From: AdaMagica @ 2021-10-18 10:50 UTC (permalink / raw)


may be the code is legal, but definitly dynamic accessibility checks should be present (which must fail in the last example)..

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is this legal?
  2021-10-16 19:00 Is this legal? Simon Belmont
  2021-10-17  8:35 ` Gautier write-only address
  2021-10-17  8:41 ` AdaMagica
@ 2021-10-19  3:50 ` Randy Brukardt
  2 siblings, 0 replies; 9+ messages in thread
From: Randy Brukardt @ 2021-10-19  3:50 UTC (permalink / raw)



"Simon Belmont" <sbelmont700@gmail.com> wrote in message 
news:6c49980a-fe55-4cea-a356-d021b417d942n@googlegroups.com...
>I'm trying to learn the 2012 changes to accessibility rules, ...
...
>Does anyone know off hand which is the correct behavior?

I can assure you that no one anywhere will *ever* know "off-hand" the 
correct behavior. :-) It takes quite a bit of looking to be sure.

...
...
>   function F (y : aliased in out str5) return access str5 is
>   begin
>      return y'Access;
>   end F;

This is always legal (we hope :-). There should be a static (or dynamic) 
check on Y when F is called that Y has an appropriate lifetime for the 
result. (I can't grok "accessibility", either. I always think in terms of 
lifetimes, and then try to translate to the wording.)

>   procedure P (x : in out T) is
>   begin
>      x.current := F(x.foo);
>   end P;

This should always be statically illegal. X here has the lifetime of P (as 
the actual lifetime is unknown). That's not long enough regardless of how 
you declare Current (since it's type is necessarily outside of P). There is 
no special accessibility rules for anonymous access components (unlike most 
other cases); they always have the accessibility (think lifetime) of the 
enclosing type.

My understanding is that AdaCore has been actively working on 
re-implementing these rules correctly, and in a few cases we've changed the 
rules as it was obvious that a better rule was possible (so Ada 2022 changes 
this some more). But none of the Ada 2022 changes should change this 
example.

                                    Randy. 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-10-19  3:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1991-11-08 20:58 Is this legal ? Boris Pelakh
  -- strict thread matches above, loose matches on Subject: below --
1991-11-09  3:20 Robert I. Eachus
1991-11-09 18:02 Bud Bach
2021-10-16 19:00 Is this legal? Simon Belmont
2021-10-17  8:35 ` Gautier write-only address
2021-10-17  8:41 ` AdaMagica
2021-10-17 18:31   ` Simon Belmont
2021-10-18 10:50     ` AdaMagica
2021-10-19  3:50 ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox