【问题标题】:Simple Ada program with wrong output输出错误的简单 Ada 程序
【发布时间】:2013-03-05 08:51:47
【问题描述】:

这里是 Ada 的初学者。 我正在尝试从这里编译和运行一个简单的 Ada 程序:http://www.dwheeler.com/lovelace/s1sf.htm

代码如下:

-- Demonstrate a trivial procedure, with another nested inside.
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;

procedure Compute is

 procedure Double(Item : in out Integer) is
 begin -- procedure Double.
   Item := Item * 2;
 end Double;

 X : Integer := 1;   -- Local variable X of type Integer.

begin -- procedure Compute
 loop
  Put(X);
  New_Line;
  Double(X);
 end loop;
end Compute;

我在 Linux 上,使用 gnat,所以我这样做了:

gnatmake -c compute.adb
gnatmake compute

这给了我可执行文件。运行可执行文件会给出一个零列表,因为它似乎将 X 初始化为 0,即使它说要将其初始化为 1,所以我应该得到一个列表 1,2,4,...

谁能解释我的代码或我的想法哪里有问题?哦,使用 gnat 有没有办法在单个命令中编译和创建可执行文件?

【问题讨论】:

    标签: compilation ada gnat


    【解决方案1】:

    我只能猜测,当你添加“-gnato”时,gnatmake 只是简单地回复了gnatmake: "compute" up to date.,给你留下了相同的可执行文件。

    brian@Gannet:~/Ada/Play$ gnatmake -gnato compute.adb
    brian@Gannet:~/Ada/Play$ ./compute
              1
              2
    ...
      536870912
     1073741824
    raised CONSTRAINT_ERROR : compute.adb:9 overflow check failed
    

    然后没有 -gnato (我不得不触摸源或我得到“最新”消息)

    brian@Gannet:~/Ada/Play$ gnatmake compute.adb
    brian@Gannet:~/Ada/Play$ ./compute
              1
              2
    ...
      536870912
     1073741824
    -2147483648
              0
              0
              0
              0
    

    随后显示为一串零。添加额外的“if”语句触及文件,强制重新编译:“if”本身并不是绝对必要的(尽管测试和防止约束错误是一件好事!)

    道德:没有 -gnato,或者更确切地说,没有标志 -gnataoE -fstack_check,Gnat 不是 Ada 编译器。

    【讨论】:

    • 您可以使用-f 标志到gnatmake 来强制完全重新编译/重建。
    • “Gnat 不是 Ada 编译器”的说法比我们必须要强。也许“不完全符合标准”会给不敬虔的人提供更少的弹药!此外,添加 -gnatE 会使您失去 GNAT 更用户友好的方面之一,几乎没有什么好处。
    • 好的,也许我们需要一个符合 Ada 的最小标志集的规范声明。我确定我在某个地方看到过一个——也许有几个,完全不同。至于“不是 Ada 编译器”可能太强了,但 OP 观察到的程序行为不符合我期待 Ada 的标准,并且不是他自己的错。
    • 我能找到的最好的副手是gcc.gnu.org/wiki/GNAT,它支持你的观察,但表明 -gnata 也是不必要的
    • 哈哈! re: gnatE 开关,我一直瞄准 gnateE 却错过了!这是一个可选开关,可生成有关异常的额外信息,我在事后诊断中发现异常准确。 gcc.gnu.org/onlinedocs/gnat_ugn_unw/Switches-for-gcc.html
    【解决方案2】:

    当你每次将整数值加倍时,循环中没有任何延迟,它会很快溢出。在 GNAT 中,溢出检查默认是关闭的,您可以使用-gnato 开关启用它。因此,当整数值溢出时,它最终会变为 0,这就是您所看到的(输出速度太快,无法看到初始数字)。

    使用-gnato 编译应该会在执行时出现约束错误。您也可以通过执行生成一行可执行文件

    gnatmake -gnato compute.adb
    

    【讨论】:

    • 我使用了 -gnato,但最终还是得到了一长串零(在整数过度增长之后)。我在计算过程中添加了一个 if 语句,现在它可以工作了(即 if X
    • 确实,Ada Reference Manual 并没有说明有符号整数乘法会触发约束错误。它只是说有符号整数乘法有其传统含义。所以这可能就是你没有得到约束错误的原因。也许其他人可以详细说明这一点。
    • 我认为这不是 Ada 参考手册问题。无论乘法做什么,对 Item 的赋值都必须引发超出范围值的约束错误。
    • 你是对的,这是应该引发错误的作业。我有点困惑,因为 ARM 提到 Constraint_Error 用于除法,但没有用于乘法,但这是另一回事。
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2016-11-12
    • 2011-08-02
    • 2015-05-24
    • 1970-01-01
    • 2013-11-13
    • 2013-11-12
    • 2012-04-18
    相关资源
    最近更新 更多