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