使用位域转换大型项目以使用更便携的东西

时间:2014-03-13 05:14:55

标签: c++ c bit-fields

我正在研究一个已经拼凑了20多年的大型软件项目(几百万行代码)。它是Fortran / C / C ++的混合体,目前针对的是Solaris&使用Sun Studio构建(虽然我可以在clang / gcc上编译它)。

我们正在将项目迁移到Linux / x86环境。我们面临的挑战之一是在项目中广泛传播了几千个位域。

目前的想法是或多或少地做这些事情:

1)无论是手动(ouch)还是通过某种重构工具(可能是用clang制作),都要更改所有位域定义以反转位域成员的顺序; e.g:

 struct SomeStruct {
 #if defined( BIG_ENDIAN )
   int x1 : size1;
   int x2 : size2;
   /* ... */
 #else
   /* ... */
   int x2 : size2;
   int x1 : size1;
 #endif
 };

2)我们发送/接收这些位域的任何点我们都必须修复字节顺序。

从表面上看,这似乎是一个可以通行的(尽管不是完全可移植的)黑客攻击,但我对它非常谨慎:

  • 容易出错(哎呀,忘了修改字节顺序; oops,更新了该结构的Solaris端而不是Linux端)
  • 虽然是Sun Studio&在目前为止测试的案例中,gcc似乎以相同的方式(在同一平台上进行测试时)打包结构/位域,我发现这里的角落情况并不会有点惊讶,并且知道这个代码基础它只是如此碰巧我们有使用那个角落的代码。
  • 从历史上看,开发人员已经被允许放弃他们想要的任何东西(例如,当我们开始运行静态分析工具时,我们发现很多代码都会丢弃const和其他各种不良内容)。如果此处涉及/任何/极端情况,则一些可疑(现有)代码可能变得更加脆弱。

如果我们已经不得不接触那么多代码以促进这一举动,我的直觉说我们应该花时间用更便携的东西替换它们,这些东西可以序列化/反序列化,所以位/字节顺序是某种东西通过API决定,而不是语言/编译器细微差别的函数。

我的问题是:位域合理的解决方案是什么?还有更好的解决方案吗? (请记住,这可能很容易触及30,000行代码或更多)

1 个答案:

答案 0 :(得分:0)

我的方法是:

  • 不要弄乱结构定义
  • 找到加载或保存(或接收或发送)数据的所有地方
  • 添加此处将转换放置到已定义的字节顺序(为方便使用您过去目标的字节顺序
  • 对于此转换,创建与硬件相关的功能,甚至更好地使用htonX和ntohX例程将数据转换为网络字节顺序(即远程BigEndian)