小编Chr*_*bbs的帖子

编译器检测任务之间的竞争条件

我的日常工作是使用安全关键的嵌入式系统。我还与客户就编写安全嵌入式代码的主题进行了一些教学/咨询。编程语言的问题总是出现,我们比较了 C、D、Ada、Erlang、Rust 等。

有一个练习我经常用于演示目的。这是一个简单的双线程程序,每个线程获取一个全局变量(初始化为 0),将其加 1 并替换它十次。然后我们推测变量在末尾可以具有的最大值 (20) 和它的最小值(我们通常在使用正式证明证明它可以是 2 之前决定 10)。

我演示的一件事是程序的 C 版本可以编译(危险),但 Rust 版本不能(好!)。今天我写了 Ada 版本,有两个惊喜我想征求意见。首先,我的程序:

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   task AddTenA;
   task AddTenB;

   --  Global variable

   x : Natural := 0;

   finished : array (0 .. 1) of Natural := (0, 0);

   --  Make sure that the compiler doesn't remove
   --  all the addition.

   pragma Volatile (x);

   task body AddTenA is
      y : Integer;
   begin
      for I in 1 .. 10 loop
         y …
Run Code Online (Sandbox Code Playgroud)

ada

7
推荐指数
1
解决办法
239
查看次数

在 Ada 中使用异常

我正在寻找风格指导。在 Python 中,异常被用作“正常”操作:

try:
    z = x/y
except ZeroDivisionError:
    z = 73.0    # set z if y is zero
Run Code Online (Sandbox Code Playgroud)

我们不是检查 y 是否接近零,而是进行除法并捕获异常。

这种类型的方法在 John Barnes 的“Programming in Ada 2012”中的 Ada 中有说明:

begin
    Tomorrow := Day'Succ(Today);
exception
    when Constraint_Error =>
        Tomorrow := Day'First;
Run Code Online (Sandbox Code Playgroud)

但是,这本书接着说“这是一个非常糟糕的例子。异常应该用于很少发生的情况......”。

我是 Ada 的新手,像我们在 Python 中所做的那样,使用异常来避免 if 语句是一种好的 Ada 编程风格吗?或者异常真的只是在 Ada 中用于令人讨厌的事情?

ada

6
推荐指数
2
解决办法
435
查看次数

循环参数的类型

一个初学者的问题,恐怕。我需要记录数组中特定元素的位置(索引)。考虑以下:

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is

    Ten : constant Positive := 10;

    type ArrayIndex is new Positive range 1 .. Ten;

    type MyRecord is record
        firstItem  : Integer;
        secondItem : Integer;
    end record;

    TheRecords : array (1 .. Ten) of MyRecord;

    indexOfElement50  :  ArrayIndex := 1;

begin

    -- set the values in TheRecords

    for i in TheRecords'Range loop
        TheRecords(i).firstItem  := i * 10;
        TheRecords(i).secondItem := i * 20;
    end loop;

    -- find which element of TheRecords has a …
Run Code Online (Sandbox Code Playgroud)

ada

4
推荐指数
1
解决办法
171
查看次数

Ada:在公共函数的前提下使用私有变量

以下是尝试用最少的代码产生我的问题(它不是一个有用的程序)。

我的问题是我想对依赖于私有变量的公共函数做一个先决条件。我必须在“私有”指标之前声明我的函数,并在该指标之后声明我的变量。这意味着我收到编译错误

question.ads:10:16: "secondPrivateVariable" 未定义问题.ads:10:40: "firstPrivateVariable" 未定义

我曾尝试将占位符定义放在函数上方,但随后出现有关定义冲突的编译错误。

package Problem is
pragma Elaborate_Body (Problem);

    function publicAPI(which : Positive) return Natural with
        Pre => secondPrivateVariable > firstPrivateVariable;
    --  should only be called when second > first

private
    --  the following variables are used by many procedures and
    --  should be kept private

    firstPrivateVariable : Natural := 7;
    secondPrivateVariable : Natural := 465;

end Problem;
Run Code Online (Sandbox Code Playgroud)

欢迎任何帮助。

ada

3
推荐指数
1
解决办法
137
查看次数

用“用”。它不仅仅消除了对前缀的需要?

以下程序 (main.adb) 将无法编译,并出现错误:

main.adb:10:15: expected private type "ThreadName" defined at config.ads:5
main.adb:10:15: found private type "Ada.Strings.Unbounded.Unbounded_String"
main.adb:11:45: expected private type "Ada.Strings.Unbounded.Unbounded_String"
main.adb:11:45: found private type "ThreadName" defined at config.ads:5
Run Code Online (Sandbox Code Playgroud)

然而,当我添加一个“使用配置;” 条款并删除配置。在 main.adb 中 MyName 声明的前缀,它编译干净并正常工作。我明白使用“use”子句只是为了让我避免使用名称空间前缀,但它似乎还有很多作用。谁能解释一下?

文件 config.ads 包含

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Config is
    type ThreadName is new Unbounded_String;
end Config;
Run Code Online (Sandbox Code Playgroud)

我的 main.adb 包含:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Config;

procedure Main is

    MyName : Config.ThreadName;

begin
    MyName := To_Unbounded_String ("Chris");
    Put_Line ( "The name …
Run Code Online (Sandbox Code Playgroud)

ada

3
推荐指数
2
解决办法
85
查看次数

位域的 Ada 模式

在 C 中,使用某种形式的 unsigned char 或 int 位来表示非排他条件是很常见的,并且通过使用 & | 和 ~ 操作符,效率极高。根据我有限的 Ada 经验,Ada 中的等效项如下面的代码所示。

with Ada.Text_IO;   use Ada.Text_IO;

procedure Main is

   type Colours is (Red, Green, Blue, Orange, Yellow, Purple);

   type BitFieldType is array (Colours) of Boolean;
   pragma Pack (BitFieldType);

   RedBitField : constant BitFieldType := (Red => True, others => False);
   GreenBitField : constant BitFieldType := (Green => True, others => False);
   BlueBitField : constant BitFieldType := (Blue => True, others => False);
   OrangeBitField : constant BitFieldType := …
Run Code Online (Sandbox Code Playgroud)

ada

1
推荐指数
2
解决办法
252
查看次数

指定具有无效值的范围的惯用方法是什么?

我经常发现我需要指定一个变量从具有某种物理意义的范围(例如,SoC 上的特定核心)获取值。但我还需要能够将其设置为“无”,这意味着“目前它不持有真正的核心标识符”。我通常使用下面给出的两种模式之一来实现此目的,但每种模式都有缺点:

  1. 第一个需要定义额外的(而且确实不必要的)类型。

  2. 第二个要求手动保持两个字段(值和定义该值是否有效的字段)对齐。编译器无法检查这种对齐方式。

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is

  --  We want to specify a Unit Identifier in the range 1 .. 10.
  --  However, sometimes we need to say that the Unit Identifier
  --  being stored is invalid.
  --
  --  The first way of doing this is to define an extended range
  --  and an Invalid Identifier.

  type Extended_Core_Identifier is new Natural range 0 .. 10;
  subtype Core_Identifier is Extended_Core_Identifier range 1 .. 10;

  Invalid_Core : constant …
Run Code Online (Sandbox Code Playgroud)

ada

1
推荐指数
1
解决办法
180
查看次数

标签 统计

ada ×7