处理代码重新定义 int 类型(uint16_t、int16_t 等)和 Boost 不喜欢它

Posted

技术标签:

【中文标题】处理代码重新定义 int 类型(uint16_t、int16_t 等)和 Boost 不喜欢它【英文标题】:Dealing with code redefining int types(uint16_t, int16_t, etc) and Boost not liking it 【发布时间】:2018-04-02 15:38:02 【问题描述】:

所以我在这里有点僵持,我不确定如何继续进行,或者它是否可以修复......

我们使用其他团队提供的第 3 方 SDK,此 SDK 必须用于我们的应用程序才能正常运行。

在这个SDK中,有这样的行

#define uint16_t UINT16
#define uint8_t UINT8

问题出在 Boost 中,更具体地说,ASIO/Details/cstdint.hpp 文件的行是

using std::uint16_t
using std::uint8_t

我的应用现在无法编译,因为它确实在运行

using std::UINT16
using std::UINT8

它抱怨这些类型显然不存在于 std 命名空间中。

这些 UINT16 和 UINT8 定义在非常大的应用程序中随处使用,因此替换它们不是很可行,我什至不确定如果我这样做 SDK 是否会起作用。

在包含 boost 头文件之前,我可以尝试 #undef 所有这些定义吗?然后重新定义它们?看起来很傻,我怀疑它是否会起作用。

有什么建议吗?

【问题讨论】:

对于初学者,请向 SDK 的维护人员提交错误报告。 (你能告诉我们是哪一个吗?) @KeithThompson 似乎它可能已经激增了一点,请参阅***.com/a/8374301/85371 - 我已经在几个 github 存储库中找到了它 “然后重新定义它们” - 为什么?您不能只编写符合标准的 C++ 代码吗?不要购买 FUD。如果UINT16 等同于std::uint16_t 那么他们有更大的问题,你不应该考虑使用那么糟糕的库。您可能会考虑使用 typedefs 来“重新创建”相同的类型名称,但我看不出它能给您带来什么(除了丑陋的类型名称) @user1024792:这些特定名称,uint16_tuint8_t 由标准库定义。 C 在 1999 ISO C 标准中引入了<stdint.h> 标头,C++ 在 2003 ISO C++ 标准中采用了它们。定义像UINT16 这样的非标准名称是可以的。重新定义像 uint16_t 这样的标准名称可能会破坏任何 C 或 C++ 代码,包括 <stdint.h><inttypes.h><cstdint><cinttypes>。该 SDK 需要更新以兼容当前的语言标准。 如果一个库的头文件破坏了其他代码(特别是如果 other code 只是以最正确和最安全的方式使用标准库功能,即命名空间限定)。这是一个错误。期间。 【参考方案1】:

问题出在 Boost 中,更具体地说,ASIO/Details/cstdint.hpp 文件的行是

这是颠倒的。问题显然出在重新定义完全通用类型名的标题中。

最可行的解决方案是永远在包含任何 boost 标头之前包含 SDK 标头。

一种拼凑的解决方法是取消定义宏。 (如果你问我,那条路是疯狂的):

#ifdef uint16_t
     #undef uint16_t
#endif

【讨论】:

Sehe 有很好的建议,这正是我过去所做的。将顽皮的 SDK 头文件包装在项目桥接头文件中,并作为包装 #undef 所有麻烦定义的一部分,可能通过提供命名空间桥 SDK 内联或 const 替代方案。根据您的工具链,您可以使用工具生成所有实时宏的转储作为翻译单元的结尾。预处理器是邪恶的。 @Eljay 我首选的攻击计划是用我自己的包装接口完全替换标题,从而只在单独的翻译单元中包含“杂乱的代码”。 “凌乱的图书馆”做其他坏事的风险很小,所以我会仔细检查任何Undefined Behaviour,比如重新定义导致违反 ODR 的事情 @Mgetz ASIO 当然严格来说并不依赖于 OpenSSL。它使用 OpenSSL 进行 TLS。此外,这只是依赖管理,它实际上与管理凌乱的包含文件毫无关系。 @sehe 问题是我们的工具使用了这些定义,所以取消定义会破坏一切?

以上是关于处理代码重新定义 int 类型(uint16_t、int16_t 等)和 Boost 不喜欢它的主要内容,如果未能解决你的问题,请参考以下文章

uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是什么?

uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是什么?

int8_tuint8_t等来源

uint8_t 数据类型

uint8类型的数据占几个字节

写入 int vs uint16_t 时的内存填充