不使用非标准‡ Scalar_Storage_Order 子句在最近的 GNAT 版本中,IPv4 标头如何通过记录表示子句与任何其他语言特性的任意组合来可移植地表示,以便“相同”的代码在 little-endian 和 big-endian 上都有效-endian 处理器,但以 IETF 所谓的网络字节顺序(这是 IETF 对 big-endian 的花哨名称)的方式在线路上(例如,通过以太网帧的有效负载)发出。在 C 中,“相同”代码可以利用预处理器宏在小端处理器上执行字节交换,但在大端处理器上是无操作的,但标准 Ada 没有预处理器。在 C++ 中,“相同”代码可以利用元模板编程 (MTP) 在小端处理器上执行字节交换,但在大端处理器上是无操作的,但标准 Ada 缺少 MTP。
(顺便说一句,当大端处理器与小端外设IC的内存映射寄存器接口时,设备驱动程序中会出现同样的问题,反之亦然:小端处理器与大端IC的内存映射寄存器接口.)
BytesPerWord : constant := 4;
BitsPerByte : constant := 8;
PowerOf2Highest : constant := BytesPerWord*BitsPerByte - 1; -- part #1 of byte-swap
type Header_IPv4 is record
Version : integer range 0 .. F#16;
IHL : integer range 0 .. F#16;
TOS : integer range 0 .. FF#16;
Length : integer range 0 .. FF#16;
Ident : integer range 0 .. FFFF#16;
Flags : integer range 0 .. 7#16;
Frag_Offs : integer range 0 .. 1FFF#16;
end record;
type Header_IPv4_Homogenous is new Header_IPv4;
for Header_IPv4_Homogenous use record -- Good-to-go for big-endian processors
Version at 0*BytesPerWord range 0 .. 3;
IHL at 0*BytesPerWord range 4 .. 7;
TOS at 0*BytesPerWord range 8 .. 15;
Length at 0*BytesPerWord range 16 .. 31;
Ident at 1*BytesPerWord range 0 .. 15;
Flags at 1*BytesPerWord range 16 .. 18;
Frag_Offs at 1*BytesPerWord range 19 .. 31;
end record;
for Header_IPv4_Homogenous'Alignment use 4;
for Header_IPv4_Homogenous'Bit_Order use High_Order_First;
type Header_IPv4_Heterogenous is new Header_IPv4;
for Header_IPv4_Heterogenous use record -- Good-to-go??? for little-endian processors?
Version at 0*BytesPerWord range PowerOf2Highest- 3 .. PowerOf2Highest- 0; -- p
IHL at 0*BytesPerWord range PowerOf2Highest- 7 .. PowerOf2Highest- 4; -- a
TOS at 0*BytesPerWord range PowerOf2Highest- 15 .. PowerOf2Highest- 8; -- r
Length at 0*BytesPerWord range PowerOf2Highest- 31 .. PowerOf2Highest- 16; -- t
Ident at 1*BytesPerWord range PowerOf2Highest- 15 .. PowerOf2Highest- 0; --
Flags at 1*BytesPerWord range PowerOf2Highest- 18 .. PowerOf2Highest- 16; -- #
Frag_Offs at 1*BytesPerWord range PowerOf2Highest- 31 .. PowerOf2Highest- 19; -- 2
end record;
for Header_IPv4_Heterogenous'Alignment use 4;
for Header_IPv4_Heterogenous'Bit_Order use Low_Order_First; -- part #3 of byte-swap
请注意“PowerOf2Highest minus”和“反转”大端位 id 从 (from,to) 顺序到 [视觉上,而不是算术上真正] (to,from) 顺序在字节交换的第 2 部分中用作粗略相当于 VHDL 的 downto,这是 VHDL 如何解决这种异构字节序问题的关键部分。(VHDL 是 Ada83 的表亲语言。)
但是现在,如何混淆集合 {Header_IPv4_Homogenous, Header_IPv4_Heterogenous} 中的哪个成员已被选为 app-domain-code 中的类型名称 Header_IPv4_Portable?使用子包?
‡ Scalar_Storage_Order已被提议作为下一版 ISO 标准 Ada 的潜在功能,但到目前为止,在 ISO 标准化委员会中还没有正式的赞助商支持该提案,因此标准化提案可能会失败并死去。另外,我将使用非 GNAT Ada 编译器,因此我无法使用 GNAT 特定的功能。