(遗留)代码大致如下所示。
#define MAKEID(a,b,c,d) (((UInt32)a)<<24 | ((UInt32)b)<<16
| ((UInt32)c)<<8 | ((UInt32)d) )
#define ID_FORM MAKEID('F','O','R','M')
//...
struct S {
int id;
int x;
double d;
// other stuff
};
//...
S s;
socket.read(&s, sizeof(s)); // read network data over struct
if (s.id == ID_FORM) { }
该代码将字符流读入结构中。 S.id 是一个 4 字符常量,例如按流(网络)顺序排列的“FORM”或“DATA”,它决定了结构其余部分的布局。所有比较都是使用预定义常量的整数。
MAKEID 宏是大端字节序,因为它将第一个(字符)参数放置在最高有效字节,这也是最低的内存地址。宏的小端版本如下所示,将第一个(字符)参数放置在最低有效字节处,即现在的最低内存地址。
#define MAKEID(a,b,c,d) (((UInt32)d)<<24 | ((UInt32)c)<<16
| ((UInt32)b)<<8 | ((UInt32)a) )
问题是如何重写它,以便它在大端和小端架构上同样有效。
不,我不想编写两个宏并使用 #ifdef 选择哪个宏。代码中的任何地方都没有其他字节序依赖关系,我不想在这里介绍一个。便携式是必经之路。
不,我不想写函数。这个常量用在函数不能去的地方。我编写了一个初始化联合的可移植函数,但代码无法编译。
我正在寻找任何类型的可移植宏或模板来进行编译时初始化。
在回答评论时,这是真正的代码。它是网络协议的一部分,另一端在大多数情况下负责处理字节序。这恰好是一个例外,另一端以网络字节顺序生成,而这一端历史上被编写为大尾数作为 4 字节字符常量,如“FORM”。我需要一种单点解决方案,而不是一种将字节序思想传播到代码中其他地方的解决方案。