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