我想将一个常量声明为Word类型的16位整数并为其赋值。为了支持Big和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#;
这对一个人来说是非常易读的,但是endian问题会导致它被误解为多种方式(例如在调试器中)。
因为我有很多行,所以我尝试了以下内容,因为它作为源代码非常紧凑。它有效,但我不确定为什么,或者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中已经看到了允许我这样做的东西,但不是我上面描述的方式。我找不到它,我不知道我会找什么。
答案 0 :(得分:1)
您拨打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
)。
您遇到字节序问题的唯一时间是您将二进制数据从一个字节序复制到另一个字节序,通过网络或文件。
如果你的调试器对此感到困惑,你需要一个更好的调试器!