这个问题可能看起来很熟悉,但我认为它与之前就同一主题提出的问题仍然有些不同(尽管“解决方案”可能是相同的,即除了扰乱第 3 方之外没有真正的解决办法代码库)
这里是:
在 Linux 和 Windows 上构建的可移植 C/C++ 框架。它利用
Microsoft C 类型 BOOL,包含在 winwindef.h(Windows 平台 SDK 的一部分)中。基础类型是“int”,如果您将值“1”定义为“TRUE”,将“0”定义为“FALSE”,则这是有意义的。
#ifdef __cplusplus extern "C" { #endif ... typedef int BOOL; ... #endif
使用预处理器分支,对于 Linux,BOOL 被合理地定义为 int(确切地说是 int32_t),以保持数据表示之间的字节大小一致性。 (我知道,这还不够,并且结束性被交换,但大多数代码仍然很简单。)
typedef int32_t BOOL;
该平台代码是专有的(我作为作者),因此可以进行更改。
当下游库或应用程序想要在 https://github.com/LAStools/LAStools/tree/master/LASlib 包含 LASlib(LAStools 的一部分)时编译器会标记冲突的 BOOL 类型,因为 LASlib 包含一个名为“mydefs.hpp”的文件,在 Windows 下编译时使用 int 作为基础类型,但对于 Linux 似乎更喜欢 C++“bool”。
#if defined(_MSC_VER) && (_MSC_VER < 1300) || defined (__MINGW32__)
typedef int BOOL;
#else
typedef bool BOOL;
#endif
我不是 Microsoftie,但这完全是倒退的(另请参阅 Using boolean values in C )。我可以想象Linux代码会产生更小的数据片段,平台分支无处不在,但恕我直言,这应该留给编译器。另外,预处理器防护不是我应该操纵的东西(并且会在 CMake 领域造成困惑),所以我有点坚持这个。
所以现在我面临着两难的境地;
- 更改 LASlib 代码(我不喜欢,它应该是第 3 方)
- 假设整个框架的 BOOL 在 Linux 中应该是“bool”,但这意味着将 C++ 类型构造映射到 C 类型,从而放弃数据大小稳定性,显然明天另一个库可以将其重新键入为 PlanetCookooDevice 类类型,因此它不能解决真正的问题。
我已阅读 Typedef redefinition with different types ('signed char' vs 'bool') 的答案和 BOOL redefinition after including minwindef.h但我觉得这个问题更严重。
那么,对于全局命名空间中甚至是“C”级别的冲突类型,是否有某种包罗万象的方法? LASlib 是一个仅包含 C++ header 的库,但我也无法 extern“C” 整个内容。
最佳答案
似乎没有“真正的”解决方案,即,如果全局命名空间中的双类型定义都在(单独的)第三方库中定义,并且您希望将它们作为下游项目的依赖项传递,则会发生冲突。它们应该由各自的作者命名。
我当前的“解决方法”是通过确保我对 BOOL 的使用仅限于仅限 Windows 的代码来避免该问题,即将平台特定部分移到 >#ifdef 守卫。在某些情况下,这意味着包装/重新输入函数返回值只是因为。丑陋,但它有效。
关于c++ - 使用 LASlib 时重新定义 BOOL typedef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58931901/