将使用位域的大型项目转换为更可移植的内容
Convert a large project using bitfields to use something more portable
我正在从事一个大型软件项目(几百万行代码),这个项目已经拼凑了20多年。它是Fortran/C/c++的混合体,目前针对Solaris;使用Sun Studio构建的(尽管我在clang/gcc上可以编译)。
我们正在将项目转移到Linux/x86环境。我们面临的挑战之一是在整个项目中自由分布的几千个位场。
目前的想法是或多或少地按照以下思路去做:
1)无论是手动(哎呦)还是通过某种重构工具(可能是clang),更改所有位字段定义以颠倒位字段成员的顺序;例如:
struct SomeStruct {
#if defined( BIG_ENDIAN )
int x1 : size1;
int x2 : size2;
/* ... */
#else
/* ... */
int x2 : size2;
int x1 : size1;
#endif
};
2)当我们发送/接收这些位域时,我们必须修改字节顺序。
从表面上看,这似乎是一个可以通过的(尽管不是完全可移植的)hack,但我对此非常怀疑:
- 这是容易出错的(哎呀,忘记修复字节顺序;哎呀,更新了Solaris端的结构体,而不是Linux端的)
- 虽然Sun Studio & &;到目前为止,在测试的用例中,gcc似乎以相同的方式打包结构体/位域(当在同一平台上测试时),我不会对发现有角落用例感到丝毫惊讶,并且知道这个代码库,它会碰巧我们有使用那个角落用例的代码。从历史上看,开发人员可以为所欲为(例如,当我们开始运行静态分析工具时,我们发现许多代码抛出了const和其他各种各样的问题)。如果这里涉及到/任何/角落的情况,一些更有问题的(现有的)代码可能会变得更加脆弱。
如果我们已经不得不修改那么多代码来促进这种移动,我的直觉告诉我,我们应该花时间用一些更可移植的东西来取代它们,这些东西可以序列化/反序列化,这样比特/字节顺序就可以通过API来决定,而不是语言/编译器的细微差别。
我的问题是:解决方案是否与位场保持合理?有没有更好的解决办法?(请记住,这很容易触及30,000行或更多的代码)
我的方法是:
- 不要弄乱结构定义
- 查找所有加载或保存(或接收或发送)数据的位置
- 在此添加一个到定义的字节顺序的转换(为了方便,使用过去目标的字节顺序 )
- 为这种转换创建依赖于硬件实现的函数,或者更好地使用htonX和ntohX例程来转换数据到网络字节序(即BigEndian)
相关文章:
- C++Union/Struct位域的实现和可移植性
- 如何在大型c++项目的可视化代码中设置调试
- 使文件夹中的所有文件可供所有项目(子目录)访问
- 具有Qt事件循环的可移植通用共享库设置
- 没有执行策略的 std::transform_reduce 是可移植的吗?
- 如何在 c++ 中正确指定 #include 路径以使程序可移植
- 创建异构顶点数据数组的可移植方法
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?
- 将 VS Code 用于跨平台可缩放C++项目
- 静态库可移植性
- 从非类型模板参数声明 constexpr 数组的可移植方法
- 如何使Visual Studio 2017 C++项目在计算机之间更具可移植性
- 使用Visual Studio项目使Opencv可移植,并删除链接错误
- C++/CLI 项目如何引用可移植类库
- 嵌入式C++项目 - 需要支持智能指针.可能的可移植性问题
- 单线程共享指针,可简单地包含在大型项目中
- Windows Metro c++ c# -如何添加WinRT可移植项目的命名空间
- 我应该如何在github上设置c++项目,使其可移植
- 从现有项目生成exe包(可移植)
- 将使用位域的大型项目转换为更可移植的内容