这个问题涉及需要在POSIX / SUS标准的必需标题中定义的各种类型。
某些类型需要在许多头文件中定义,我想知道实现这一目标的正确和合规方式是什么。
例如,查看<time.h>
标头规范:
包含标题可能会使所有符号都可见 &LT; signal.h中&GT;报头中。
这很简单,<signal.h>
包含<time.h>
。
现在怎么样:
clock_t , size_t , time_t , clockid_t ,以及 timer_t 类型的定义如下所述 &LT; SYS / types.h中&GT;
据我了解,这意味着我们不能简单地在<sys/types.h>
中加入<time.h>
,因为这会暴露出比所需更多的符号。
所以有人可以证实这一点吗?
是否会违反标准合规性以包含<sys/types.h>
?
如果是这样,我认为最好的解决方案是为每种类型创建一个特定的标题,这样就可以从任何地方看到特定的类型,而不必担心其他符号。
还有其他好的解决方案吗?
最后一点,C标准的类型怎么样? POSIX / SUS规范中的许多类型都是整数类型,可能需要有固定的宽度。
标准是否可以从特定标题中包含<stdint.h>
,还是会违反合规性?
答案 0 :(得分:1)
你是对的,从其他标题中公开不需要的类型和声明是不合格的。
一个微不足道的(但是,就预处理器花费时间来打开文件而言,价格昂贵)解决方案是为每种类型设置一个单独的标头,并且只要您需要,例如time_t
,执行:
#include <types/time_t.h>
当然types/time_t.h
会有适当的多重包含守卫。
还有许多其他方法可以达到同样的目的。 glibc和gcc使用的方法是在包含一个标题之前定义特殊的“必需”宏,该标题要求它除了提供一种或多种类型之外什么都不做。这个解决方案也非常昂贵,可能比上面的更多,因为它打破了编译器对多包含保护的启发式。编译器不能忽视重复包含;它必须在每次包含文件时解析文件。
我们在musl中的方式是使用单个文件bits/alltypes.h
,其中包含多个标头和宏所需的所有类型的定义,以控制所公开的文件。它由一个隐藏所有宏逻辑的简单sed脚本生成:
答案 1 :(得分:0)
<子> 在阅读这个问题后,我打开了无法抗拒在 THE 最大的UNIX兼容(严格来说,只有“类UNIX”)开源项目中检查这一点 - Linux Kernel (现在几乎总是担心标准合规性)。 子>
time.h
标头将定义一些内部标志,然后包含types.h
,其定义 ALL 类型,但#ifdef
内的类型检查是否有内部标记标志已定义。
因此,归结为以下几点:
time.h
#define
用于建立上下文的相关内部标志。 #include
编辑的上下文选择性地公开功能。这样可以提供模块化标题,而不必担心意外地暴露出超出要求的符号。