Ada程序在Linux中工作,但不在GPS中Windows 10

问题描述:

在此先感谢您的帮助。我目前正在做一些关于ada编程的初学者工作,我已经安装了GNAT编程工作室(GPS),从http://libre.adacore.com/download/configurations# 我有Windows 10 64位。我得到了下面的代码在学校:Ada程序在Linux中工作,但不在GPS中Windows 10

pragma Task_Dispatching_Policy(FIFO_Within_Priorities); 

with Ada.Text_IO; use Ada.Text_IO; 
with Ada.Real_Time; use Ada.Real_Time; 

procedure PeriodicTasks is 

    Start : Time; 

    package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration); 
    package Int_IO is new Ada.Text_IO.Integer_IO(Integer); 

    task type T(Id: Integer; Period : Integer) is 
     pragma Priority(Id); 
    end; 

    task body T is 
     Next : Time; 
     X : Integer; 
    begin 
     Next := Start; 
     loop 
      Next := Next + Milliseconds(Period); 
      -- Some dummy function 
      X := 0; 
      for Index in 1..5000000 loop 
       X := X + Index; 
      end loop; 
      Duration_IO.Put(To_Duration(Clock - Start), 3, 3); 
      Put(" : "); 
      Int_IO.Put(Id, 2); 
      Put_Line(""); 
      delay until Next; 
     end loop; 
    end T; 

    -- Example Task 
    Task_P10 : T(10, 250); 
    Task_P12 : T(12, 500); 
    Task_P14 : T(14, 500); 
    Task_P16 : T(16, 250); 
    Task_P18 : T(18, 500); 
    Task_P20 : T(20, 250); 
begin 
    Start := Clock; 
    null; 
end PeriodicTasks; 

我在GPS打开的文件,它内置(没有错误),并运行它,但它并没有表现出任何的打印输出。我听说有时候你会遇到多核CPU的问题,所以每次打开gps.exe时,CPU关联性都只设置为一个CPU,并且始终“以管理员身份运行”。然而,这也不起作用,我没有输出。 我决定使用Oracle Virtual Box,并设置只有一个处理器的Ubuntu OS(32位)。安装GNT工具,用gnatmake编译,用./periodictasks运行,然后猜测程序做了它应该做什么并打印出信息。

经过了这么长的一段漫长的故事,有人知道为什么会发生这种情况吗?它可能是一个64位与32位的情况?

非常感谢!

直到最近,GNAT默认没有检查整数溢出。它确实检查了约束错误,例如将0分配给Positive

我们很多人都认为这是编译器开发人员的一个奇怪选择,因为它导致了许多问题,其根本原因是无法处理整数溢出。最近的变化导致我们认为开发人员现在同意!

你的问题出现了,因为该语句

for Index in 1..5000000 loop 
    X := X + Index; 
end loop; 

这最终会与X〜10^13,其不适合在一个32位的整数的(这将适合在一个64位的整数,但如果不是所有的GNAT平台,那将是一个Long_Long_Integer)。

您的Windows编译器很可能是GNAT GPL 2016,它显示了新的行为,而Ubuntu编译器是旧的FSF GCC。

你可以告诉你的Windows编译器使用编译器开关-gnato0的旧行为。

你可以告诉你的Ubuntu编译器使用编译器开关-gnato的新行为。

要获得任务(否则默默地死去)上的未处理异常的异常信息,你可以在你的主程序的开头添加

GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Unhandled_Raise); 

+0

值得注意的是,旧的行为对于Ada编译器来说是不正确的。直到最近,如果您通过了“-gnato”参数,GNAT才是Ada编译器。 –

+1

参见[*§8.4GNAT *中的溢出检查处理](https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gnat_ugn/Overflow-Check-Handling-in-GNAT.html#Overflow-Check -HANDling-in-GNAT) – trashgod

+0

非常感谢你!!!!!我修改了项目 - >构建属性,添加了-gnato0开关及其工作!非常感谢! –

在开始执行时,有垃圾印刷和打印信息的唯一任务是Task_P20 & Task_P18

正如§9.2 Task Execution - Task Activation讨论的,任务的执行PeriodicTasks第一条语句之前一起激活。尽管所有任务都在运行,但在初始化Start之前,没有,某些或所有任务可能会尝试产生输出。至少,初始化Start接近其声明越好,

Start : Time := Clock; 

和不离身空,

begin 
    null; 
end PeriodicTasks; 

而且,未能激活一个任务变成了完成任务,不产生输出。

+0

非常感谢!我仍然不明白的唯一原因是这只发生在Windows而不是Ubuntu虚拟机中。我可以对Windows环境做些什么来使其表现得像Ubuntu VM或其他方式。我会发表另一个问题。再次感谢! –

+0

[错误](http://www.adaic.org/resources/add_content/docs/95style/html/sec_5/5-9.html)程序可能在不同的平台上表现不一致;我希望修正后的程序能够一致地执行。 – trashgod