【发布时间】:2021-12-23 13:02:24
【问题描述】:
问题:
最近我们的 C 共享库遇到了以下问题。
该库定义了一个类似这样的方法:
typedef enum {A, B, C} some_enum;
typedef struct {some_enum e; time_t t; char* data;} request;
void f(request);
我们使用 clang 及其交叉编译功能为多种架构编译了该库。其中一个平台是 Windows 32 位。
这就是问题所在:当尝试在使用 MSVC 32 位编译器的示例中使用该库时,该示例因 seg 错误而失败。
原因:在 MSVC 32 位 time_t 中为 8 个字节,而在 Windows 32 位的 clang 编译中假定为 4 个字节。
显然,如果我们使用固定宽度的整数类型,例如int64_t,则永远不会出现此问题。
问题:
对于可移植的 C 共享库中的原始类型,是否有既定的最佳实践?
例如,在 C 共享库接口中完全避免任何非固定宽度整数类型是最佳实践吗?
例如,enums 在可移植 C 库中是否“允许”(就最佳实践而言)?
【问题讨论】:
-
请注意,这与编译器无关:您使用标准 C 运行时库(具体为
time.h)的两个不兼容实现来编译共享库和应用程序代码。 -
@yugr 谢谢,这是一个非常有用的观察,我错过了。我认为它仍然与编译器有关,因为我希望在 Linux Arm 64 架构中完成的编译与该系统上可用的默认 C 运行时库兼容。
-
并非总是如此,例如Linux 上不同的 libc 实现(Glibc、newlib、musl 等)肯定不兼容。至于你的情况,你能用
-E编译有问题的代码并检查哪个头文件提供time_t吗? (对于 MSVC,您可以通过在 Visual Studio 编辑器中“打开”time.h来执行此操作。 -
注意:Windows 有
__time64_t和__time32_t。_USE_32BIT_TIME_Tmacro determines 其中一个time_t是类型定义的。 -
谢谢@YakovGalka,很高兴知道。
标签: c shared-libraries portability