Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada: package does not allow a body

Tags:

ada

gnat

Using the GNAT compiler, when I try to compile or check semantic on the following files, I get some variation of the error package "Foo" does not allow a body. I'm new to the language and can't find an answer to this seemingly basic problem anywhere on the Internet. Please advise.

foo.ads

package Foo is
   type Shape_Enum is (Circle, Triangle, Rectangle);
end Foo;

foo.adb

package body Foo is
   procedure Foo is
      MyShape : Shape_Enum;
   begin
      MyShape := Rectangle;
   end Foo;   
end Foo;
like image 754
weberc2 Avatar asked Sep 27 '12 21:09

weberc2


2 Answers

A package is only allowed to have a body if the specification includes something that requires a body. (This avoid problems where an optional body might accidentally be left out of a build.)

You have a procedure in the body of the package (Foo.Foo), but there's no way to call it.

If you add a declaration:

procedure Foo;

to the specification, that should (a) fix the error, and (b) permit the procedure to be called by clients of the package. Or you can use pragma Elaborate_Body; to require it to have a body if you don't want the procedure to be visible to clients.

Incidentally, there's nothing special about a procedure with the same name as the package that contains it (unlike in C++, where such a function is a constructor for the containing class). It would probably be clearer to use a different name.

See section 7.2 of the Ada Reference Manual (I'm using a recent draft of the 2012 standard):

A package_body shall be the completion of a previous package_declaration or generic_package_declaration. A library package_declaration or library generic_package_declaration shall not have a body unless it requires a body; pragma Elaborate_Body can be used to require a library_unit_declaration to have a body (see 10.2.1) if it would not otherwise require one.

like image 102
Keith Thompson Avatar answered Sep 28 '22 07:09

Keith Thompson


You could also declare the function to be private by adding:

private
    procedure Foo;

to the specification. Which will prevent it's use outside of the package.

like image 34
Melllvar Avatar answered Sep 28 '22 08:09

Melllvar