我想知道我是否可以依赖标准标题中包含保护的特定定义。如果我使用Visual Studio查看我的系统,我可以看到,例如,stdint.h定义了_STDINT
。我的问题是我是否可以依赖这个#define
来编译其他编译器。基本上,我可以安全地做这样的事情:
#ifndef _STDINT
typedef char int8_t;
#endif
我知道这可能看起来很愚蠢。为什么不包括stdint.h你说呢?好吧,我正在编写可能部署嵌入式目标的代码,这可能不包括某些标准c头文件。但是,我希望能够在可用时使用它们。因此,我希望能够在具有int main()
的文件中选择是否要包含stdint.h。
答案 0 :(得分:1)
不幸的是没有:)。这就是为什么autoconf
和朋友之类的东西存在,以便能够实际编译小程序并提前测试以确定系统是否包含特定的符号和标题;在程序的单一传递编译中无法完成的事情。
例如,“Visual Studio stdint.h
”实际上并不存在于较旧的Visual Studio版本中。
正如上面所指出的,正确的解决方案是使用某种源外配置系统来确定要做什么。
有时候,您可能可以使用更简单的东西,具体取决于您使用stdint.h
的子集的大小:
使用项目前缀固定类型(例如my_I32
),并将它们定义为int
;如果事先知道所有目标平台都将int
作为32位整数。
使用项目提供的stdint.h
并将此文件的路径放在预处理器搜索路径中。请注意,这要求您的项目和此项目的任何依赖项(包括系统标头)仅使用此文件中定义的声明子集。
答案 1 :(得分:0)
您可以依赖标准库头来准确(并且不超过)指定要声明的内容。这意味着:
如果某个功能是可选功能,则该标准会指定一个功能测试宏,您可以使用#if
或#ifdef
检查该宏,以告诉您它是否在您的平台上可用。例如threads.h
在C11中是可选的,因此标准指定如果标头不可用,则将__STDC_NO_THREADS__
定义为1.
如果某个功能不是可选功能,您应该可以认为它存在!如果它不存在,则编译器不符合语言版本,并且您最好希望在文档中明确说明这些内容,因为您已进入实现定义的区域。
< / LI>许多功能都以宏的形式提供,或者与相关的宏定义一起提供;因此,您可以测试是否存在与整个标题无关的此类功能。
因此,对于stdint.h
的情况,没有提供功能测试宏,因为标头不是可选的。如果它不存在,编译器确实应该记录这一点,而不是声称标准合规性。但是,stdint.h
中的某些功能是可选的,因此可以单独测试其相关的宏。
例如,7.20(int8_t
等)中描述的精确宽度整数类型需要关联的宏定义来描述它们的最大值和最小值(并且这些宏特别不是定义了类型是否不可用),因此您可以通过测试在包含标题后是否定义int8_t
来测试INT8_MAX
的具体可用性。