Ada83 声明中记录的未经检查的转换

Ada83 Unchecked Conversion of Record in Declaration

我想将常量声明为 Word 类型的 16 位整数并为其赋值。为了支持 Big Endian 和 Little Endian 平台之间的可移植性,我不能安全地使用这样的分配:

Special_Value : Constant Word := 16#1234#;

因为字节顺序可能会被误解。

所以我使用这样的记录:

   Type Double_Byte Is Record
      Byte_1 : Byte; -- most significant byte
      Byte_0 : Byte; -- least significant byte
   End Record;
   For Double_Byte Use Record
      Byte_1 At 0 Range 0..7;  
      Byte_0 At 0 Range 8..15; 
   End Record;

但是,在某些情况下,我有大量的预配置分配看起来像这样:

Value_1 : Constant Word := 15#1234#;

这对于一个人来说是非常可读的,但是端序问题导致它在很多方面被误解(例如,包括在调试器中)。

因为我有很多行要执行此操作,所以我尝试了以下内容,因为它作为源代码相当紧凑。它正在工作,但我不确定为什么,或者 Ada 参考手册的哪一部分涵盖了这个概念:

Value_1 : Constant Word := DByte_To_Word((Byte_1 => 16#12#, 
                                           Byte_0 => 16#34#));

其中 DByte_To_Word 定义为

Function DByte_To_Word          Is New Unchecked_Conversion(Double_Byte, Word);

我想我在 ARM 中看到了一些允许我这样做的东西,但不是我上面描述的方式。我找不到它,我不知道我要搜索什么。

您给 DByte_To_Word 的电话没有任何异常; (Byte_1 => 16#12#, Byte_0 => 16#34#)Double_Byte 类型的完全合法的记录聚合,参见 LRM83 4.3.1

但是!但!确实,在大端机器上,Word 的第一个(最低地址)字节将包含 16#12#,而在小端机器上它将包含 16#34#。 CPU 负责所有这些;如果您打印 Special_Value 的值,您将得到 16#1234#(或 0x1234),无论计算机实现哪种字节顺序。

您唯一会遇到字节序问题的情况是当您通过网络或文件将二进制数据从一种字节序复制到另一种字节序时。

如果您的调试器对此感到困惑,您需要更好的调试器!