编译时检查是否存在stdint.h

8
我正在处理传统的嵌入式C代码,该代码在头文件中使用typedef关键字定义了类型uint8_t、uint16_t和uint32_t。假设文件typedefs.h包含这些定义。
在我的新C源模块中,我包括stdint.h。我还包括其他头文件,它们在层次结构中的某个位置包括typedefs.h。正如预期的那样,编译器会抱怨多个已定义符号。
我想修改传统文件typedefs.h,以便仅在未包括stdint.h或更好地未定义uint*_t类型时才声明这些类型。
我的理解是由于typedef不是预处理器指令,因此不能使用#ifndef。那么我该如何告诉编译器不要定义uint*_t,如果它们已经存在(或者已经包括了stdint.h)?
注:如果C规范为头文件定义了标准包含保护定义,则此操作将很容易。
FWIW,我正在使用Green Hills编译器4.24,用于ARM9处理器。
3个回答

7

我认为 stdint.h 应该定义一些宏来表示其所定义的类型的限制。你可以使用 #ifdef 等方式来测试这些限制。

#ifndef UINT32_MAX
  typdef ... uint32_t;
  #define UINT32_MAX ...
  ...
#endif

编辑:最初使用了UINT32_MIN,但正如Jens Gustedt所指出的那样,这是唯一一个不会发生符号/无符号和min/max组合的情况。


1
哦,UINT32_MIN不存在。可以使用UINT32_MAX或者INT32_MIN - Jens Gustedt
@Jens:以下两个链接似乎表明这些定义是必需的:1)http://www.opengroup.org/onlinepubs/000095399/basedefs/stdint.h.html 2)http://linux-documentation.com/en/man/man0p/stdint.h.html - torak
1
是的,我知道,但我的观点是对于无符号类型,不需要使用MIN函数,因为它总是为0。 - Jens Gustedt
@Jens:啊,光线变暗了。谢谢! - torak
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Bill

5
只需修复旧有的头文件,始终包含stdint.h以获取这些类型,删除重复定义,并为缺少它的损坏系统提供一个可替换的文件stdint.h

0
如果您正在使用UNIX系统,则应该退一步并使用像autoconf(1)或automake(1)这样的配置包。它专门处理此类问题。

这是一个嵌入式系统,不使用Unix或Linux,而是使用ThreadX。此外,它是在stdint.h成为标准之前编写的。 - Thomas Matthews
@Thomas:你可能在ThreadX以外的操作系统上运行Green Hills编译器,比如Linux或Windows,对吧?很少有嵌入式编译器是自托管的。话虽如此,autoconf/automake听起来对于这种情况来说有点过度,它们解决的是不同的问题:“我该如何让我的代码在多个平台上编译,无论它们是否有stdint.h?”而不是“我该如何让使用stdint.h的新代码停止与定义了一些相同类型的旧代码发生冲突?” - bk1e

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接