5
votes

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;
3
Once you get it working, I'd suggest renaming it to "Adarocks". Compilers are sensitive, and you'll want to try to get back on its good side.T.E.D.
I've taken the liberty of editing the question to change the package name.Keith Thompson
Whatever floats your boat. Thanks again for the answer. Accepted and upvoted.weberc2

3 Answers

10
votes

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.

3
votes

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.

1
votes

Apparently Ada needs you to explicitly force a package body with pragma elaborate_body. I found the answer here:

http://objectmix.com/ada/338459-erreur-de-compilation.html#post1225079 (thank God I speak French):

ORIGINAL

entier_paquetage.adb:4:01: spec of this package does not allow a body

Si la spec ne demande pas un corps, le corps n'est pas autorisé. On peut forcer un corps en mettant "pragma elaborate_body;" dans la spec.

English

If the spec doesn't demand (or ask for) a body, the body will not be authorize . We can force a body by putting "pragma elaborate_body;"