C:为什么size_t不是C关键字?

时间:2009-04-11 08:03:39

标签: c types sizeof size-t

sizeof是一个C 关键字。它返回名为size_t的类型的大小。但是,size_t 不是关键字,但主要在 stddef.h 中定义,也可能在其他C标准头文件中定义。

考虑一种情况,您希望创建一个包含任何C标准头文件或库的C程序。 (例如,如果您正在创建操作系统内核。)现在,在这样的代码中,可以使用sizeof(它是一个C关键字,因此它是语言的一部分 ),但它返回的类型(size_t)不可用!

这不是C标准规范中的某种问题吗?你能澄清一下吗?

10 个答案:

答案 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_tunsigned 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和C ++语言的设计者总是倾向于在可能和合理的情况下在库中实现语言功能
  • 向语言添加关键字可能会为现有的遗留代码体带来问题。这是他们通常不愿意添加新关键字的另一个原因。

例如,在讨论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)

来自MSDN

  

应用sizeof运算符时   对于char类型的对象,它产生1

即使你没有stddef.h可用/包含且不知道size_t,使用sizeof你可以获得相对于char的对象大小。

答案 8 :(得分:1)

size_t 不是必需的关键字。不同的体系结构通常具有不同的整体类型大小。例如,如果64位计算机没有决定使 int 成为64位数据类型,那么 unsigned long long 可能会 size_t

如果你为编译器创建了内置类型的size,那么它将消除交叉编译的能力。

此外, sizeof 更像是一个神奇的编译时宏(想想c ++模板),它解释了为什么它是关键字而不是定义的类型。

答案 9 :(得分:1)

原因很简单,因为它不是一种基本类型。如果您查找C标准,您会发现基本类型包括intchar等但不包括size_t。为什么这样?正如其他人已经指出的那样,size_t是一种特定于实现的类型(即能够保持任何对象的“C字节”数量的类型)。

另一方面,sizeof是(一元)运算符。所有运营商都是关键字。