4

因此,我们使用的供应商提供了一个库(主要用于 C,具有一些 C++ 支持),它执行以下操作:

#ifndef int64_t
#define int64_t s_int64
#endif
#ifndef int32_t
#define int32_t s_int32
#endif
#ifndef int16_t
#define int16_t s_int16
#endif
#ifndef int8_t
#define int8_t  s_int8
#endif

在他们图书馆深处的一个标题中。现在的问题是,一旦他们的库包含在简单的 C++11 代码中,例如:

#include <iostream>

#include <vendor/library.h>

int main(void)
{
  std::int32_t std_i = 0;
  return std_i;
}

立即出现编译器错误,(s_int32不在std::)。所以问题是,除了唠叨供应商来解决这个问题,有没有办法在我们的代码中解决这个问题?(顺便说一句。我尝试过的东西,#include <cstdint> 他们的标题之前,没有运气;extern "C"包装,没有运气。标题是安装的,/usr/include/所以我猜也无法控制包含顺序......)

4

4 回答 4

21

您可以取消定义它们的定义。

#undef int64_t
#undef int32_t
#undef int16_t
#undef int8_t
于 2013-10-15T09:30:49.253 回答
5

预处理器有一个聪明的特性:防止在替换宏时递归!因此,您可以这样定义它们:

#define int64_t int64_t
#define int32_t int32_t
#define int16_t int16_t
#define int8_t int8_t

包括供应商的标题之前。这样它们就不会被重新定义(因为它们正在使用#ifndef),并且它们对您的其余代码保持预期的含义。

于 2013-10-15T09:47:01.673 回答
4

如果不查看文件中的其他内容,很难找到一个 100% 有效的解决方案。

但是,您可以尝试的一个想法如下(注意 - 我在我的编译器中模糊地尝试过这个,但我不保证它会在任何其他编译器中工作)。

创建一个包含其定义的文件,但作为 typedefs:

typedef s_int64 int64_t;
...

然后一些编译器允许您在命令行上指定要包含的文件之前的任何其他文件...例如,gcc 具有-include开关,因此您指定包含此文件。

然后,同样在您的命令行上,您可以将映射定义为自己:

-Dint64_t=int64_t

甚至将定义放在上面的文件中:

#define int64_t int64_t

结果是,理论上,#defines不会干扰任何其他代码(它们不应该做任何事情——尽管我不确定你是否最终会得到递归扩展?)。并且当您创建了typedef正确的类型时,供应商代码应该仍然有效。

将 typedef 放入强制包含的文件中的原因是,您希望确保它首先被包含在内。

然后你应该让供应商更新他们的代码以使用typedef. 您是客户,他们想向您推销产品。

所有理论头脑。

于 2013-10-15T09:47:40.440 回答
0

他们正在使用#ifndef宏,这意味着:如果未定义,则值为...

只需先用您的价值观定义它:

#define int64_t (xx)
#define int32_t (xx)
#define int16_t (xx)
#define int8_t  (xx)
于 2013-10-15T09:32:14.570 回答