Ada程序在Linux中运行,但不在GPS Windows 10中运行

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

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文件,build立它(没有错误),并运行它,但它不显示任何打印输出。 我听说有时候你会遇到多核CPU的问题,所以每次打开gps.exe时,CPU亲缘关系都只被设置为一个CPU,并且总是“以pipe理员身份运行”。 然而,这也没有工作,我得不到输出。 我决定使用Oracle Virtual Box,并设置只有一个处理器的Ubuntu OS(32位)。 安装GNT工具,用gnatmake编译,运行./periodictasks,然后猜测程序做了什么,然后打印出信息。

毕竟这个漫长的故事,有人知道这是为什么发生? 它可能是一个64位与32位的情况?

非常感谢你!

Solutions Collecting From Web of "Ada程序在Linux中运行,但不在GPS Windows 10中运行"

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

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

你的问题是因为这个陈述而出现的

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

这将以Long_Long_Integer ^ 13结束,不适合一个32位整数(它适合于一个64位整数,但如果不是所有的GNAT平台,这将是一个Long_Long_Integer )。

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

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

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

为了在任务中得到未处理异常的异常消息(否则它会静默地),你可以添加

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

在你的主程序开始。

在执行开始时,会有垃圾打印,唯一的打印信息任务是Task_P20Task_P18

如第9.2节“ 任务执行 – 任务激活”中所述 ,在执行PeriodicTasks的第一个语句之前,这些任务将一起激活。 尽管所有任务都在运行,但 Start初始化之前 ,没有,某些或所有任务可能会尝试产生输出。 尽可能地尽量接近声明来初始化Start

 Start : Time := Clock; 

并把身体留空,

 begin null; end PeriodicTasks; 

而且,一个没有激活的任务就成了一个完成的任务,没有产出。