C:为什么size_t不是C关键字?
sizeof
是一个C 关键字 。 它返回名为size_t
的类型的大小。 但是, size_t
不是关键字,而是主要在stddef.h
定义,也可能是其他C标准头文件。
考虑一种情况,您希望创建一个不包含任何C标准头文件或库的C程序。 (例如,如果你正在创建一个OS内核。)现在,在这样的代码中,可以使用sizeof
(它是一个C关键字,因此它是语言的一部分),但它返回的类型( size_t
)不可用!
这不是C标准规范中的某种问题吗? 你能澄清一下吗?
它不会返回size_t类型的值,因为size_t本身不是具体类型,而是未指定内置类型的typedef。 Typedef标识符(例如size_t)完全等同于它们各自的底层类型(并在编译时转换为它们)。 如果size_t在您的平台上定义为unsigned int,则sizeof在您的系统上编译时返回unsigned int。 size_t只是维护可移植性的一种方便方法,如果您按名称明确使用它,则只需要包含在stddef.h中。
sizeof
是一个关键字,因为尽管它的名称和用法,它是一个像+
或=
或<
而不是像printf()
或atoi()
或fgets()
这样的printf()
。 很多人忘记(或者只是不知道) sizeof
实际上是一个运算符,并且总是在编译时而不是在运行时解析。
C语言不需要size_t
是一种可用的,一致的语言。 这只是标准库的一部分。 C语言需要所有运营商。 如果C代替+
,则使用关键字plus
来添加数字,那么您将使其成为运算符。
此外,我将size_t
s半隐式重铸为unsigned int
(和常规int
,但Kernighan和Ritchie有一天会为此打击我)。 如果你愿意,你可以将sizeof
的返回类型分配给int,但在我的工作中我通常只是将它直接传递给malloc()
或其他东西。
来自C标准的一些头部被定义用于独立环境,即适合用于例如操作系统内核中。 它们没有定义任何函数,只定义和typedef。
它们是float.h,iso646.h,limits.h,stdarg.h,stdbool.h,stddef.h和stdint.h。
在使用操作系统时,从这些标头开始并不是一个坏主意。 让它们可用会使内核中的许多事情变得更容易。 特别是stdint.h会变得很方便(uint32_t等)。
这不是C标准规范中的某种问题吗?
查看C的托管实现与独立C实现之间的区别。 需要独立(C99)实现来提供标头:
这些标题根本不定义任何函数。 它们定义了某些特定于编译器的语言部分(例如,
的offsetof
,以及
的变量参数列表宏和类型),但它们可以在不实际构建的情况下进行处理作为完整的关键词进入语言。
这意味着即使在您的假设内核中,您也应该期望C编译器提供这些头和任何底层支持函数 – 即使您提供其他所有内容。
我认为size_t
不是关键字的主要原因是:
- 它没有令人信服的理由。 如果可能且合理的话,C和C ++语言的设计者总是倾向于在库中实现语言特性
- 向一种语言添加关键字可能会对现有的遗留代码体造成问题。 这是他们通常不愿意添加新关键字的另一个原因。
例如,在讨论C ++标准的下一个主要修订时, Stroustrup有这样的说法 :
C ++ 0x的改进应该以这样的方式完成,即生成的语言更容易学习和使用。 委员会的经验法则包括:
...
- 首选标准库设施到语言扩展
...
即使您正在处理内核,也没有理由不包含stddef.h – 它为您的特定编译器定义了任何代码所需的类型大小。
另请注意,几乎所有C编译器都是自编译的。 因此,sizeof运算符的实际编译器代码将使用size_t并引用与用户代码相同的stddef.h文件。
来自MSDN :
当sizeof运算符应用于char类型的对象时,它产生1
即使你没有stddef.h可用/包含但不知道size_t,使用sizeof你可以获得相对于char的对象大小。
size_t实际上是一个类型 – 通常是unsigned int。 Sizeof是一个给出类型大小的运算符。 sizeof返回的类型实际上是特定于实现的,而不是C标准。 它只是一个整数。
编辑:要非常清楚,您不需要size_t类型才能使用sizeof。 我认为您正在寻找的答案是 – 是的,它是不一致的。 但是, 没关系。 您仍然可以在没有头文件中的size_t定义的情况下正确使用sizeof。
size_t不是必需的关键字。 不同的体系结构通常具有不同的整体类型大小。 例如,64位机器可能有一个无符号长long作为size_t,如果他们没有决定使int为64位数据类型。
如果为编译器创建内置类型的size,那么它将消除进行交叉编译的能力。
此外, sizeof更像是一个神奇的编译时宏(想想c ++模板),它解释了为什么它是一个关键字而不是定义的类型。
原因很简单,因为它不是一种基本类型。 如果你查看C标准,你会发现基本类型包括int
, char
等,但不是size_t
。 为什么这样? 正如其他人已经指出的那样, size_t
是一种特定于实现的类型(即能够保持任何对象的“C字节”数量的大小的类型)。
另一方面, sizeof
是(一元)运算符。 所有运营商都是关键词