Ada 程序在 Linux 中有效,但在 GPS Windows 中无效 10
Ada program works in Linux but not in GPS Windows 10
在此先感谢您的帮助。我目前正在做一些关于 ada 编程的初学者工作,我已经从 http://libre.adacore.com/download/configurations# 安装了 GNAT Programming Studio (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 中打开文件,构建它(没有错误)并 运行 它但它没有显示任何打印输出。我听说有时你会遇到多核 CPUs 的问题,所以每次打开 gps.exe 时,CPU affinity 都设置为只有一个 CPU 并且它总是 "Run as Administrator"。但是,这也不起作用,我没有输出。
我决定使用 Oracle Virtual Box 并设置一个只有一个处理器的 Ubuntu OS(32 位)。安装了 GNAT 工具,用 gnatmake 编译,运行 用 ./periodictasks,你猜怎么着,程序做了它应该做的并打印了信息。
说了这么多,有人知道为什么会这样吗?会不会是 64 位与 32 位的情况?
非常感谢!
直到最近,GNAT 才默认不检查整数溢出。它确实检查了约束错误,例如将 0 分配给 Positive
.
我们中的许多人认为这是编译器开发人员的一个奇怪选择,因为它导致了许多问题,其根本原因是未能处理整数溢出。最近的变化让我们假设开发人员现在同意了!
你的问题是因为语句
for Index in 1..5000000 loop
X := X + Index;
end loop;
这将以 X ~ 10^13 结尾,它不适合 32 位整数(它适合 64 位整数,但大多数情况下都是 Long_Long_Integer
如果不是所有 GNAT 平台)。
您的 Windows 编译器可能是 GNAT GPL 2016,它显示了新行为,而 Ubuntu 编译器是较旧的 FSF GCC。
您可以使用编译器开关 -gnato0
告诉您的 Windows 编译器使用旧行为。
您可以使用编译器开关 -gnato
告诉您的 Ubuntu 编译器使用新行为。
要获取有关任务中未处理异常的异常消息(否则会静默终止),您可以添加
GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Unhandled_Raise);
在主程序的开头。
at the beginning of the execution, there is garbage printed and the only tasks that print information are Task_P20
& Task_P18
.
如 §9.2 Task Execution - Task Activation 中所述,任务在 PeriodicTasks
的第一条语句执行之前一起激活。尽管所有任务都是 运行,但不,某些或所有任务可能会在 Start
初始化之前尝试生成输出 。至少,初始化 Start
尽可能接近它的声明,
Start : Time := Clock;
并让主体空着,
begin
null;
end PeriodicTasks;
此外,未能激活的任务将成为已完成的任务,不会产生任何输出。
在此先感谢您的帮助。我目前正在做一些关于 ada 编程的初学者工作,我已经从 http://libre.adacore.com/download/configurations# 安装了 GNAT Programming Studio (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 中打开文件,构建它(没有错误)并 运行 它但它没有显示任何打印输出。我听说有时你会遇到多核 CPUs 的问题,所以每次打开 gps.exe 时,CPU affinity 都设置为只有一个 CPU 并且它总是 "Run as Administrator"。但是,这也不起作用,我没有输出。 我决定使用 Oracle Virtual Box 并设置一个只有一个处理器的 Ubuntu OS(32 位)。安装了 GNAT 工具,用 gnatmake 编译,运行 用 ./periodictasks,你猜怎么着,程序做了它应该做的并打印了信息。
说了这么多,有人知道为什么会这样吗?会不会是 64 位与 32 位的情况?
非常感谢!
直到最近,GNAT 才默认不检查整数溢出。它确实检查了约束错误,例如将 0 分配给 Positive
.
我们中的许多人认为这是编译器开发人员的一个奇怪选择,因为它导致了许多问题,其根本原因是未能处理整数溢出。最近的变化让我们假设开发人员现在同意了!
你的问题是因为语句
for Index in 1..5000000 loop
X := X + Index;
end loop;
这将以 X ~ 10^13 结尾,它不适合 32 位整数(它适合 64 位整数,但大多数情况下都是 Long_Long_Integer
如果不是所有 GNAT 平台)。
您的 Windows 编译器可能是 GNAT GPL 2016,它显示了新行为,而 Ubuntu 编译器是较旧的 FSF GCC。
您可以使用编译器开关 -gnato0
告诉您的 Windows 编译器使用旧行为。
您可以使用编译器开关 -gnato
告诉您的 Ubuntu 编译器使用新行为。
要获取有关任务中未处理异常的异常消息(否则会静默终止),您可以添加
GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Unhandled_Raise);
在主程序的开头。
at the beginning of the execution, there is garbage printed and the only tasks that print information are
Task_P20
&Task_P18
.
如 §9.2 Task Execution - Task Activation 中所述,任务在 PeriodicTasks
的第一条语句执行之前一起激活。尽管所有任务都是 运行,但不,某些或所有任务可能会在 Start
初始化之前尝试生成输出 。至少,初始化 Start
尽可能接近它的声明,
Start : Time := Clock;
并让主体空着,
begin
null;
end PeriodicTasks;
此外,未能激活的任务将成为已完成的任务,不会产生任何输出。