Ada 95 defects for scope / visibility: the incipient problem

The requirement is that all numeric and string variables are globally visible to all components.
(The requirement is a derivative of the project to move a perfect software program onto an ASIC via VHDL (a subset of Ada) by either of the parts vendors massive modelling tools that support many parts. Hence if one deems this a masked homework assignment, then please refrain.)

To that end, the PACKAGE with all such declarations of definitions is pkg_defs.adB.

The PACKAGE with all PROCEDURES including Main as procdurs.adB is invoked as:

– The ubiquitous slug of packages required by Ada 95 listed here.
WITH pkg_defs ; USE pkg_defs ;

PACKAGE BODY procdurs IS
– Procedure bodies listed here
– – None of the Procedures can see the WITH’d variable definitions <<<<<<<<<<<<<<<
END procdurs ;

Added later: An immediate workaround is to declare all definitions before the BEGIN in procdurs.adB for an unwieldy file to edit.

I guess it depends on your compiler, but in GNAT you need the package spec of Pkg_Defs to be an .ads file, not .adb. Either way as long as the numeric and string variables are declared in the spec of Pkg_Defs and not the body, it all works fine. I tested it on GNAT with no troubles.

This all happily compiles in GNAT. Other compilers should have no trouble:

pkg_defs.ads

    package Pkg_Defs is
        Num_1 : Integer := 100;
        Num_2 : Integer := 1000;
        Str_1 : String  := "Hello";
        Str_2 : String  := "World";
    end Pkg_Defs;

procedures.ads

    package Procedures is
        procedure Op_1;
        procedure Op_2;
    end Procedures;

procedures.adb

    with Pkg_Defs;
    use Pkg_Defs;
    
    package body Procedures is
        procedure Op_1 is
            Total : Integer := Num_1 + Num_2;
        begin
            Ada.Text_IO.Put_Line(Num_1'Image & " +" & Num_2'Image & " =" & Total'Image);
        end Op_1;
        
        procedure Op_2 is
        begin
            Ada.Text_IO.Put_Line(Str_1 & " " & Str_2);
        end Op_2;
    end Procedures;
1 Like

Thank you for reply. I was in fact mistakenly using pkg_defs.adB instead of pkg_defs.adS, which is not clearly stated to me as a legal rule in RM95, but maybe an archivist can list the index listing I missed there if off the top of the head.

It’s not a language rule. It’s a compiler vendor rule. The Ada RM specifies the lexical structure of the program but allows the compiler vendor to dictate things like file extensions. I believe there have been some compilers that let you put both spec and body in the same file and have a single extension like *.ada. Some compilers like GNAT have much stricter requirements by default, but the RM doesn’t dictate those things.

The language specification talked about a Library, and vendors followed that suggestion. You could compile any old file with Ada in it, and the compiler would work out what it was and enter it in the Library in the right place; later compilations could find it (unless the Library was corrupted, which probably meant recompiling everything).

The contract for what’s now GNAT was let to NYU with the requirement that it be open source, and the team decided that GCC would be the best basis. Richard Stallman wouldn’t accept the idea of a Library, so the NYU team came up with what we have now, a file-based system.

So, in GNAT, when the compiler sees with Foo;, it knows to look for foo.ads.

You can change the rule in your GNAT Project file if you must, possibly to cope with mixed-compiler projects (e.g. embedded vs desktop).

3 Likes

I am not so sure about that because a compiler vendor rule approaches Appendix A, is it, in the C standard where everyone agrees to render floating point at run-time, to make C a notorious kluge where the same ANSI standard float code can produce different results in supposedly ANSI standard C compilers. This is why I avoid GNAT because it is written in C, rather than in Ada or native assembler, the point being that gcc is not god-like, although arguably viewable as a religion.

From Ada 95 RM.7.1: “A package_declaration or generic_package_declaration requires a completion (a body) if it contains any declarative_item that requires a completion, but whose completion is not in its package_specification.” [For “whose”, read “which.”]

Ada folklore interprets the word salad of 7.1 as “simply defines a package_declaration as being the same as a package_specification.” But that is not necessarily implied by the quote above to me because it means a package_declaration is interchangeable or substitutable by a package_specification, which I am not sure as a beginner is always correct. I try not to interpret ill-formed exposition as other than the textus receptus. What follows is that the RM95 is also not god-like.

That says you you have to have a package body if something in your package spec requires a completion and that completion is not currently found in the package spec. It doesn’t mention anything about where that body must be located, nor what file types, nor whether or not the body could be in the same file or not.

The RM doesn’t specify anything about requiring .ads or .adb file extensions.

Okay, got it, thanks.