例如,C11规定应在以下头文件中声明size_t
:
在阅读C11时,我发现在多个标准头文件中声明了许多其他数据类型。
size_t
的情况下。为什么不简单地在stddef.h
?size_t
。它们是否保证在这些头文件中具有相同的定义?假设size_t,我们假设。为简单起见,为什么不在stddef.h中呢?
该类型用于所有这些文件中的函数声明。如果它没有在<stdio.h>
中声明,除非你首先包含<stddef.h>
,否则你会得到一个编译错误。
假设C编译器在这些头文件中实现了size_t。它们是否保证在这些头文件中具有相同的定义?
是的,他们将有相同的定义。通常,该值在单个位置定义在其他包含的单独包含文件中。
在某些情况下,可以使用编译器选项或定义来修改定义,例如,允许32/64位编译的编译器可以将size_t
定义为32或64位无符号实体,具体取决于编译器命令行上定义的目标。
作为在stdio.h
中声明的函数的一个示例,需要size_t预先声明,请考虑snprintf()
。实际上,如果你想在你的代码中使用它,你需要做的就是#include <stdio.h>
。如果size_t只在stddef.h
中声明,那么你必须这样做
#include <stddef.h>
#include <stdio.h>
不仅如此,但由于stdio.h
声明snprintf
是否使用它,每次在stdio.h
中需要任何东西时都必须包含这两个文件以避免编译器错误; stdio.h
将对stddef.h
产生人为依赖。这会导致您的源代码变得更长且更脆弱(请注意,如果您颠倒两个指令的顺序,它也会破坏)。相反,我们编写头文件使它们独立并且不依赖于其他头文件,这就是C标准化委员会为标准库决定的内容。
by和in之间存在细微差别 - 只要在包含指定标头时定义了size_t
,就可以完全自由地在单个标头中定义size_t
。那么,你有两个选择:
是的,size_t必须定义为指定的,(typedef unsigned long size_t;
):
typedef unsigned int size_t
要么
size_t
他们并没有说你必须理智,他们只是说它需要在任何人包含其中一个标题时定义,因为它们依赖于它被定义并且可以独立使用。简而言之,如果你定义依赖于size_t
的东西,那么#include <stdio.h>
必须首先(先前)被定义。
你这样做(或者更确切地说,在哪里)取决于你的实现。
首先,当一个人做一个<stdio.h>
时,并不要求任何地方存在一个名为stdio.h的文件,或者编译器对这样的文件做任何事情。相反,要求是这样的行必须使得所有被指定为与#include <stdio.h>
相关联的标识符根据规范来定义。如果编译器看到#include <stdio.h>
只是允许使用硬编码到编译器中的某些标识符,那将是完全合法的。因为编译器供应商使事情符合规范要求的最简单方法是让stdio.h
指令通过预处理器运行某些文件size_t
的文本,这就是许多编译器所做的,但这不是必需的。
当规范列出应该声明#include
的“文件”时,它真正说的是命名任何一个文件的size_t
指令应该在全局范围内创建该标识符。这可以通过让所有列出的名称的文件包含size_t
的定义,或者将#include
内置到编译器中,但只启用编译器的内置定义来查看带有指定名称之一的qazxswpoi指令。