comp.lang.ada
 help / color / mirror / Atom feed
* Optional body for nested generic
@ 2011-09-20 12:48 Simon Wright
  2011-09-20 15:00 ` Adam Beneschan
  2011-09-20 15:15 ` Robert A Duff
  0 siblings, 2 replies; 9+ messages in thread
From: Simon Wright @ 2011-09-20 12:48 UTC (permalink / raw)


I was surprised to find that GNAT makes it optional to have a body for a
nested generic package (in the code below, gpack1 has an empty body,
gpack2 doesn't have a body at all).

package Pack is
   pragma Elaborate_Body;
   generic
   package Gpack1 is
      procedure Proc;
      pragma Import (C, Proc, "proc");
   end Gpack1;
   generic
   package Gpack2 is
      procedure Proc;
      pragma Import (C, Proc, "proc");
   end Gpack2;
end Pack;

package body Pack is
   package body Gpack1 is
   end Gpack1;
end Pack;

I suppose that the reasoning for disallowing unrequired bodies (roughly,
making it impossible to obsolete the ada library by adding/removing
something with no other impact) only applies at library level, where
there's a correspondence to a file?



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

* Re: Optional body for nested generic
  2011-09-20 12:48 Optional body for nested generic Simon Wright
@ 2011-09-20 15:00 ` Adam Beneschan
  2011-09-20 15:18   ` Simon Wright
  2011-09-20 15:15 ` Robert A Duff
  1 sibling, 1 reply; 9+ messages in thread
From: Adam Beneschan @ 2011-09-20 15:00 UTC (permalink / raw)


On Sep 20, 5:48 am, Simon Wright <si...@pushface.org> wrote:
> I was surprised to find that GNAT makes it optional to have a body for a
                               ^^^^

I believe you misspelled "Ada".

> nested generic package (in the code below, gpack1 has an empty body,
> gpack2 doesn't have a body at all).
>
> package Pack is
>    pragma Elaborate_Body;
>    generic
>    package Gpack1 is
>       procedure Proc;
>       pragma Import (C, Proc, "proc");
>    end Gpack1;
>    generic
>    package Gpack2 is
>       procedure Proc;
>       pragma Import (C, Proc, "proc");
>    end Gpack2;
> end Pack;
>
> package body Pack is
>    package body Gpack1 is
>    end Gpack1;
> end Pack;
>
> I suppose that the reasoning for disallowing unrequired bodies (roughly,
> making it impossible to obsolete the ada library by adding/removing
> something with no other impact) only applies at library level, where
> there's a correspondence to a file?

The rule indeed applies only to library packages (including generic
packages); it's in RM 7.2(4).  Since it's a language rule and not a
GNAT rule, it doesn't have anything to do wtih "correspondence to a
file"; however, since any compiler *allows* library package specs and
bodies to be processed in different runs of the compiler (even if it
doesn't require this), allowing a package body that isn't needed can
lead to confusion (if, say, a package spec is changed from one that
requires a body to one that doesn't---what happens to the body that
was previously compiled?).  See the Ada 95 Rationale, 10.4: "In Ada
83, if a package does not require a body, but has one nevertheless
(perhaps to do some initialization), its body can become out-of-date,
and be silently omitted form a subsequent build of an executable
program.  This can lead to mysterious run-time failures...".  This
reasoning doesn't apply in non-library package cases.

                         -- Adam



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

* Re: Optional body for nested generic
  2011-09-20 12:48 Optional body for nested generic Simon Wright
  2011-09-20 15:00 ` Adam Beneschan
@ 2011-09-20 15:15 ` Robert A Duff
  2011-09-21 15:01   ` Adam Beneschan
  1 sibling, 1 reply; 9+ messages in thread
From: Robert A Duff @ 2011-09-20 15:15 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> I was surprised to find that GNAT makes it optional to have a body for a
> nested generic package (in the code below, gpack1 has an empty body,
> gpack2 doesn't have a body at all).
>
> package Pack is
>    pragma Elaborate_Body;
>    generic
>    package Gpack1 is
>       procedure Proc;
>       pragma Import (C, Proc, "proc");
>    end Gpack1;
>    generic
>    package Gpack2 is
>       procedure Proc;
>       pragma Import (C, Proc, "proc");
>    end Gpack2;
> end Pack;
>
> package body Pack is
>    package body Gpack1 is
>    end Gpack1;
> end Pack;
>
> I suppose that the reasoning for disallowing unrequired bodies (roughly,
> making it impossible to obsolete the ada library by adding/removing
> something with no other impact) only applies at library level, where
> there's a correspondence to a file?

Yes, the reasoning only applies at library level.  That was the
thinking during the Ada 9X project.

However, I think the reasoning is bogus in the first place,
although I didn't realize it at the time.

Suppose there were no Elab_Body above.
If a file pack.adb (using the GNAT convention) exists,
then it should be compiled and linked in as part of the program.

If you delete pack.adb, then it should vanish.  The problem was
that Ada 83 compilers didn't do that -- they would link in the
obsolete object code for Pack body.

Likewise, if you created a new pack.adb, they wouldn't notice unless
you explicitly "compiled it into the program library".  Note that very
early versions of GNAT had this same "bug", thus proving that this
is an implementation issue, not a language issue.  (Those early
versions defined pack.adb to NOT exist in the program library unless
pack.ads required it for some reason, completely defeating the purpose.)
Long since fixed!

In a truly source-based program library, these problems just don't
exist.

- Bob



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

* Re: Optional body for nested generic
  2011-09-20 15:00 ` Adam Beneschan
@ 2011-09-20 15:18   ` Simon Wright
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Wright @ 2011-09-20 15:18 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> On Sep 20, 5:48 am, Simon Wright <si...@pushface.org> wrote:
>> I was surprised to find that GNAT makes it optional to have a body for a
>                               ^^^^
>
> I believe you misspelled "Ada".

I knew for a fact that GNAT allowed it, but there have been cases where
GNAT allowed things it shouldn't have.

Thanks for confirming my suspicions.



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

* Re: Optional body for nested generic
  2011-09-20 15:15 ` Robert A Duff
@ 2011-09-21 15:01   ` Adam Beneschan
  2011-09-22  3:43     ` Randy Brukardt
  0 siblings, 1 reply; 9+ messages in thread
From: Adam Beneschan @ 2011-09-21 15:01 UTC (permalink / raw)


On Sep 20, 8:15 am, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:
>
> Yes, the reasoning only applies at library level.  That was the
> thinking during the Ada 9X project.
>
> However, I think the reasoning is bogus in the first place,
> although I didn't realize it at the time.
>
> Suppose there were no Elab_Body above.
> If a file pack.adb (using the GNAT convention) exists,
> then it should be compiled and linked in as part of the program.
>
> If you delete pack.adb, then it should vanish.  The problem was
> that Ada 83 compilers didn't do that -- they would link in the
> obsolete object code for Pack body.
>
> Likewise, if you created a new pack.adb, they wouldn't notice unless
> you explicitly "compiled it into the program library".  Note that very
> early versions of GNAT had this same "bug", thus proving that this
> is an implementation issue, not a language issue.  (Those early
> versions defined pack.adb to NOT exist in the program library unless
> pack.ads required it for some reason, completely defeating the purpose.)
> Long since fixed!
>
> In a truly source-based program library, these problems just don't
> exist.

I think there was a problem in Ada 83, because it had more
(apparently) concrete concepts of the program library, compilations,
recompilations, program units becoming obsolete and being removed from
the library.  The Ada 95 Rationale pointed out a real problem: if a
library package specification that does not require a body has a body,
then when the specification is recompiled, the body, according to the
language rules, becomes obsolete and is removed from the library.  If
you forget to submit the body for recompilation, this changes the
meaning of the program if the body contains an initialization part or
declares any tasks.  So in that context, I think the new rule (that a
library package body cannot be present unless it's required) was
needed.

However, Ada 95 also removed a lot of the concepts that had been IMHO
overspecified in Ada 83 (AARM 10.1(4.c): "The interactions between
language issues and environmental issues are left open in Ada 95....
In Ada 83, the concept of the program library, for example, appeared
to be quite concrete, although the rules had no force...").  Now, I
think the basic rule about recompilations and obsolete units and such
is just that the implementation has to get it right.  (E.g. if a
library spec is recompiled, and it has been changed in a way that
makes the body illegal, the body can't become part of the final
program, and a partition can't be created if the body is required; the
notion of an "obsolete" unit isn't necessary at all.)  Because of this
change, the other new rule (that disallowed a body unless required)
probably wasn't necessary.

Still, I'm not unhappy with the rule, since it can prevent accidents.
Suppose, for example, that a specification of P declares some
procedures, and the body contains the code for those procedures.  Then
the user decides he wants the procedures moved somewhere else, so he
eliminates them so that P now declares only types.  It's too easy to
make a mistake that causes P's body to be included in the final
executable anyway.  I think it's beneficial to force the programmer to
take some action (in this case, adding a pragma) if P's body is still
supposed to be included.

                           -- Adam





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

* Re: Optional body for nested generic
  2011-09-21 15:01   ` Adam Beneschan
@ 2011-09-22  3:43     ` Randy Brukardt
  2011-09-22 14:28       ` Robert A Duff
  0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2011-09-22  3:43 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:8ad3b626-8608-4561-8d8f-bf11e7e8efc0@en1g2000vbb.googlegroups.com...
>On Sep 20, 8:15 am, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:
...
>> However, I think the reasoning is bogus in the first place,
>> although I didn't realize it at the time.

[Lots of discussion of a source-based compiler model.]

>> In a truly source-based program library, these problems just don't
>> exist.

Sure, but most Ada compilers aren't source-based! Assuming that is 
essentially the same as saying Ada = GNAT, and not even AdaCore really wants 
that situation.

>I think there was a problem in Ada 83, because it had more
>(apparently) concrete concepts of the program library, compilations,
>recompilations, program units becoming obsolete and being removed from
>the library.  The Ada 95 Rationale pointed out a real problem: if a
>library package specification that does not require a body has a body,
>then when the specification is recompiled, the body, according to the
>language rules, becomes obsolete and is removed from the library.  If
>you forget to submit the body for recompilation, this changes the
>meaning of the program if the body contains an initialization part or
>declares any tasks.  So in that context, I think the new rule (that a
>library package body cannot be present unless it's required) was
>needed.

This was NOT an implementation issue in Ada 83 -- the ACVC *required* the 
unit be be ignored. Janus/Ada had given an error message in this case, and I 
had to spend a week or so figuring out how to change our binder so that it 
could silently (other than a warning) drop the offending unit.

And having done so, I was repeatedly bitten by programs that didn't work 
because some body was no longer elaborating the initialization (especially 
the Janus/Ada compiler). We eventually abandoned doing almost anything at 
elaboration time; besides this problem, we also were having a lot of trouble 
keeping things happening in the "right" order. Unfortunately, elaboration, 
at least as defined in Ada 83, seemed a lot more useful than it really was.

The Ada 95 rule would have prevented most of that trouble.

...
>Still, I'm not unhappy with the rule, since it can prevent accidents.
>Suppose, for example, that a specification of P declares some
>procedures, and the body contains the code for those procedures.  Then
>the user decides he wants the procedures moved somewhere else, so he
>eliminates them so that P now declares only types.  It's too easy to
>make a mistake that causes P's body to be included in the final
>executable anyway.  I think it's beneficial to force the programmer to
>take some action (in this case, adding a pragma) if P's body is still
>supposed to be included.

Yup. And having the rule gave us a good reason to get rid of the ACVC test 
that was causing all of the pain in the first place. I'm not sure the 
relaxation of the rules would have allowed that - it would have allowed 
automatic recompilation, but I'm not sure it would have allowed an error in 
that case (and it *should* be an error if it is not automatically 
recompiled, IMHO).

                                         Randy.





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

* Re: Optional body for nested generic
  2011-09-22  3:43     ` Randy Brukardt
@ 2011-09-22 14:28       ` Robert A Duff
  2011-09-22 23:03         ` Randy Brukardt
  0 siblings, 1 reply; 9+ messages in thread
From: Robert A Duff @ 2011-09-22 14:28 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Adam Beneschan" <adam@irvine.com> wrote in message 
> news:8ad3b626-8608-4561-8d8f-bf11e7e8efc0@en1g2000vbb.googlegroups.com...
>>On Sep 20, 8:15 am, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:
> ...
>>> However, I think the reasoning is bogus in the first place,
>>> although I didn't realize it at the time.
>
> [Lots of discussion of a source-based compiler model.]
>
>>> In a truly source-based program library, these problems just don't
>>> exist.
>
> Sure, but most Ada compilers aren't source-based! Assuming that is 
> essentially the same as saying Ada = GNAT, and not even AdaCore really wants 
> that situation.

OK, but clearly a non-source-based compiler can do the right thing,
too. [1]

>>I think there was a problem in Ada 83, because it had more
>>(apparently) concrete concepts of the program library, compilations,
>>recompilations, program units becoming obsolete and being removed from
>>the library.  The Ada 95 Rationale pointed out a real problem: if a
>>library package specification that does not require a body has a body,
>>then when the specification is recompiled, the body, according to the
>>language rules, becomes obsolete and is removed from the library.  If
>>you forget to submit the body for recompilation, this changes the
>>meaning of the program if the body contains an initialization part or
>>declares any tasks.  So in that context, I think the new rule (that a
>>library package body cannot be present unless it's required) was
>>needed.
>
> This was NOT an implementation issue in Ada 83 -- the ACVC *required* the 
> unit be be ignored.

Then I claim the ACVC was broken.  Maybe the RM was broken, too (it was
surely unclear at best), but my claim is that the fix we added in Ada 95
was not necessary.

The attitude in the early days of Ada 83 was too rigid, as if the RM had
been handed down from Mount Sanai.  Nowadays, we're much more willing to
say "the RM requires something idiotic (or is unclear about it);
therefore that's not what it means".

>...Janus/Ada had given an error message in this case, and I 
> had to spend a week or so figuring out how to change our binder so that it 
> could silently (other than a warning) drop the offending unit.

OK, that's proof of my statement [1] above.  You did it right.
You should have disputed the test, because it's truly idiotic
to silently ignore things like that.  (And I claim that the
Ada 83 RM didn't really require the bad behavior -- I rewrote
chapter 10 mainly to CLARIFY that fact, not to change it.)

On the other hand, warnings are just as good as errors, IMHO,
especially if you have a "treat warnings as errors" switch,
as GNAT does.

> And having done so, I was repeatedly bitten by programs that didn't work 
> because some body was no longer elaborating the initialization (especially 
> the Janus/Ada compiler). We eventually abandoned doing almost anything at 
> elaboration time; besides this problem, we also were having a lot of trouble 
> keeping things happening in the "right" order. Unfortunately, elaboration, 
> at least as defined in Ada 83, seemed a lot more useful than it really was.

Elaboration is rather broken in Ada.  The rules should be checked
statically (compile/link time).  And the allowance for different
compilers to choose different orders of elaboration is just Wrong.
AdaCore customers have no end of trouble with that, when porting code.

> The Ada 95 rule would have prevented most of that trouble.

Yes, it's sufficient, but not necessary.

> ...
>>Still, I'm not unhappy with the rule, since it can prevent accidents.
>>Suppose, for example, that a specification of P declares some
>>procedures, and the body contains the code for those procedures.  Then
>>the user decides he wants the procedures moved somewhere else, so he
>>eliminates them so that P now declares only types.  It's too easy to
>>make a mistake that causes P's body to be included in the final
>>executable anyway.  I think it's beneficial to force the programmer to
>>take some action (in this case, adding a pragma) if P's body is still
>>supposed to be included.
>
> Yup. And having the rule gave us a good reason to get rid of the ACVC test 
> that was causing all of the pain in the first place. I'm not sure the 
> relaxation of the rules would have allowed that - it would have allowed 
> automatic recompilation, but I'm not sure it would have allowed an error in 
> that case (and it *should* be an error if it is not automatically 
> recompiled, IMHO).

Agreed.

- Bob



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

* Re: Optional body for nested generic
  2011-09-22 14:28       ` Robert A Duff
@ 2011-09-22 23:03         ` Randy Brukardt
  2011-09-23  0:03           ` Adam Beneschan
  0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2011-09-22 23:03 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcc8vpg1wje.fsf@shell01.TheWorld.com...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
...
>>...Janus/Ada had given an error message in this case, and I
>> had to spend a week or so figuring out how to change our binder so that 
>> it
>> could silently (other than a warning) drop the offending unit.
>
> OK, that's proof of my statement [1] above.  You did it right.
> You should have disputed the test, because it's truly idiotic
> to silently ignore things like that.  (And I claim that the
> Ada 83 RM didn't really require the bad behavior -- I rewrote
> chapter 10 mainly to CLARIFY that fact, not to change it.)

The test was disputed (not by us, I don't think), and the ARG at the time 
confirmed it (I'm pretty sure there is an Ada 83 AI to this effect, but I'm 
too lazy to look it up right now). Ada 83 compilers had no choice but to 
follow this behavior.

So the Ada 83 RM (at least as interpreted by the ARG and/or AVO) did require 
this behavior. The ACVC test was confirmed as correct.

I think you could make a good case that the Ada 83 ARG was nuts in this case 
(and several other cases as well) -- but that doesn't change the history. 
The reason Ada 95 has this rule, explicitly, was to overrule that previous 
horrible ARG decision. You could not have done that by interpretation alone.

So I continue to maintain that the rule was necessary, even if the reason 
that was the case was more political than technical.

                                      Randy.





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

* Re: Optional body for nested generic
  2011-09-22 23:03         ` Randy Brukardt
@ 2011-09-23  0:03           ` Adam Beneschan
  0 siblings, 0 replies; 9+ messages in thread
From: Adam Beneschan @ 2011-09-23  0:03 UTC (permalink / raw)


On Sep 22, 4:03 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:

> The test was disputed (not by us, I don't think), and the ARG at the time
> confirmed it (I'm pretty sure there is an Ada 83 AI to this effect, but I'm
> too lazy to look it up right now).

It's probably AI83-400.  There's also AI83-856, but there's no
discussion in that AI and it might be essentially a duplicate.

                       -- Adam



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

end of thread, other threads:[~2011-09-23  0:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-20 12:48 Optional body for nested generic Simon Wright
2011-09-20 15:00 ` Adam Beneschan
2011-09-20 15:18   ` Simon Wright
2011-09-20 15:15 ` Robert A Duff
2011-09-21 15:01   ` Adam Beneschan
2011-09-22  3:43     ` Randy Brukardt
2011-09-22 14:28       ` Robert A Duff
2011-09-22 23:03         ` Randy Brukardt
2011-09-23  0:03           ` Adam Beneschan

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