字节序¶
bitproto 的编码格式在所有平台上都是 小端序 (little-endian):编码后字节序列中索引最低的字节存放字段的最低有效位。这是编码格式的固定属性,与运行编码器或解码器的机器无关 —— 字节序不同的两端始终可以互通。
各语言的支持情况¶
宿主机 CPU 是否为大端序只对 C 有影响,因为只有 C 会直接读取整数字段的原始内存字节。Python 和 Go 是对整数的 值 做移位和掩码运算,这种方式天然与字节序无关。
目标语言 |
比特如何搬运 |
大端序主机 |
|---|---|---|
Python |
对 Python 整数做数值运算 |
始终正确 |
Go |
对定型字段做数值移位 |
始终正确 |
C(标准模式) |
|
正确 |
C(优化模式) |
生成的比特拷贝语句 |
正确 |
因此 Go 和 Python 不需要做任何特殊处理。本页接下来的内容都是关于 C 的。
C 标准模式¶
The C library (lib/c/bitproto.c) detects a big-endian host automatically
(via __BYTE_ORDER__ for GCC/Clang, __ARM_BIG_ENDIAN for
ACLE-compatible Arm toolchains such as TI Arm Clang, __big_endian__ for
legacy TI ARM CGT, __BIG_ENDIAN__ for other toolchains, and
__LITTLE_ENDIAN__ == 0 for IAR) and selects an endian-neutral code path.
You may also force it by defining BP_BIG_ENDIAN when compiling the library,
for toolchains that expose none of these macros:
$ cc -DBP_BIG_ENDIAN -c bitproto.c
在小端序主机上,运行库逐字节保持不变,因此对常见的目标平台没有任何性能影响。
C 优化模式¶
优化模式 会生成直接的比特拷贝语句,通过整数字段的内存字节来读写它们。为了在小端序和大端序主机上都保持正确,bitproto 默认会生成两份等价的代码路径,并用一个预处理宏来区分:
#ifndef BP_BIG_ENDIAN
// fast byte-pointer path (little-endian hosts)
#else
// portable bit-shift path (big-endian hosts)
#endif
A big-endian host is auto-detected (via __BYTE_ORDER__ for GCC/Clang,
__ARM_BIG_ENDIAN for ACLE-compatible Arm toolchains such as TI Arm Clang,
__big_endian__ for legacy TI ARM CGT, __BIG_ENDIAN__ for other
toolchains, and __LITTLE_ENDIAN__ == 0 for IAR); you may also force the
big-endian path by defining BP_BIG_ENDIAN when compiling the generated code.
The little-endian path is identical to earlier bitproto releases, so there is no
performance change on little-endian targets — only the generated source is a
little larger.
--endian 选项¶
如果你已经知道目标平台的字节序,可以用 --endian 选项去掉用不到的那份代码路径,从而缩小生成的源码(仅在优化模式下有效):
# default: both paths, host auto-detected
$ bitproto c example.bitproto -O
# only the fast little-endian path (smaller output, no big-endian support)
$ bitproto c example.bitproto -O --endian=little
# only the portable big-endian path
$ bitproto c example.bitproto -O --endian=big
--endian 只影响优化模式下的 C/C++ 代码。它不会影响编码格式,也不影响 Go 和 Python。