使用Ada进行软件工程:存根; 单独和编译单位

yCa*_*ran 4 compilation ada stub

我有机械工程背景,但我有兴趣与Ada学习良好的软件工程实践.我有几个问题.

Q1.如果我理解正确,那么有人可以编写一个包规范(ads)文件,编译它然后编译使用该包的主程序.稍后,当人们知道要在包体中包含什么时,可以编写和编译后者.之后,现在可以运行主程序.我试过这个,我想确认这是一个好习惯.

Q2.我的第二个问题是关于存根(子单元)和SEPARATE的使用.假设我有一个主程序如下:

    WITH Ada.Float_Text_IO;
    WITH Ada.Text_IO;
    WITH Ada.Integer_Text_IO;

    PROCEDURE TEST2 IS
    A,B      : FLOAT;
    N        : INTEGER;

    PROCEDURE INPUT(A,B: OUT FLOAT; N: OUT INTEGER) IS SEPARATE;

    BEGIN -- main program
      INPUT(A,B,N);
      Ada.Float_Text_IO.Put(Item => A);
      Ada.Text_IO.New_line;
      Ada.Integer_Text_IO.Put(Item => N);
    END TEST2;
Run Code Online (Sandbox Code Playgroud)

然后我在单独的文件中有过程INPUT:

separate(TEST2)
PROCEDURE INPUT(A,B: OUT FLOAT; N: OUT INTEGER) IS
   BEGIN
      Ada.Float_Text_IO.Get(Item => A);
      Ada.Text_IO.New_line;
      Ada.Float_Text_IO.Get(Item => B);
      Ada.Text_IO.New_line;
      Ada.Integer_Text_IO.Get(Item => N);
   END INPUT;
Run Code Online (Sandbox Code Playgroud)

我的问题:

a)AdaGIDE建议我将INPUT过程文件保存为input.adb.但是在编译主程序test2时,我收到警告:

warning: subunit "TEST2.INPUT" in file "test2-input.adb" not found
cannot generate code for file test2.adb (missing subunits)
Run Code Online (Sandbox Code Playgroud)

对于AdaGIDE,这更像是一个错误,因为上述警告出现在消息之前:

Compiling...
Done--error detected
Run Code Online (Sandbox Code Playgroud)

所以我将input.adb文件重命名为test2-input.adb,正如AdaGIDE在编译时向我建议的那样.现在编译主文件时,我没有任何警告.我现在的问题是如果可以写的话

PROCEDURE INPUT(A,B: OUT FLOAT; N: OUT INTEGER) IS
Run Code Online (Sandbox Code Playgroud)

就像我在子单元文件test2-input.adb中所做的那样,或者写一个更具描述性的术语更好

PROCEDURE TEST2-INPUT(A,B: OUT FLOAT; N: OUT INTEGER) IS
Run Code Online (Sandbox Code Playgroud)

强调程序输入有一个父程序test2?这个想法来自AdaGIDE,正如我上面提到的那样暗示我关于test2-input.adb.

b)我的下一个问题:

如果我理解编译顺序,那么我应该首先编译主文件test2.adb然后编译stub test2-input.adb.在编译存根时,我收到错误消息:

cannot generate code for file test2-input.adb (subunit)
Done--error detected
Run Code Online (Sandbox Code Playgroud)

但是,我现在可以为test2.adb执行绑定和链接并运行该程序.

我想通过尝试编译存根test2-input.adb或者是否应该编译它来确定我是否做错了?

Q3.有子单元有什么用?是否只是将一个大型程序分解成更小的部分?我知道如果没有在子单元中的BEGIN和END之间放置任何语句,则会出现错误.所以这意味着总是必须在那里发表声明.如果以后想要编写语句,可以在子单元中的BEGIN和END之间放置一个NULL语句,稍后再返回后者.这是软件工程在实践中完成的方式吗?

非常感谢...

Mar*_*c C 7

Q1:这是很好的做法.

通过将包规范视为规范,您可以将其提供给其他开发人员,以便他们知道如何与您的代码进行交互.

Q2:我认为AdaGIDE实际上使用GNAT编译器进行所有编译,因此它实际上是负责可接受文件名的GNAT.(这可以配置,但除非你有一个非常令人信服的理由这样做,简单地使用GNAT/AdaGIDE的文件命名约定要简单得多.)但是,与你的问题更相关的是,没有强有力的理由包括父母单位作为单独单位名称的一部分.但是看到Q3的答案......

问题3:在第一版Ada-Ada 83中引入了子单元 - 部分是为了帮助模块化代码,并允许延迟开发和编译.但是,Ada软件开发实践几乎放弃了子单元的使用,所有的过程/函数/任务/等机构都简单地全部保存在包的主体中.它们仍然在某些领域使用,例如,如果可能需要特定于平台的子程序版本,但在大多数情况下它们很少使用.它留下较少的文件来跟踪,并将包的实现代码保持在一起.所以我强烈建议您忽略子单元功能并将所有实现代码放在包体中.