C:为什么 size_t 不是 C 关键字?
sizeof
是一个 C 关键字。 它以名为 size_t
的类型返回大小。 但是,size_t
不是关键字,而是主要在 stddef.h
以及可能其他 C 标准标头中定义文件也是如此。
考虑这样一个场景:您想要创建一个不包含任何 C 标准头文件或库的 C 程序。 (例如,如果您正在创建操作系统内核。)现在,在这样的代码中,可以使用 sizeof
(它是一个 C 关键字,因此它是语言的一部分< /em>),但它返回的类型(size_t
)不可用!
这是否表明 C 标准规范存在某种问题? 你能澄清一下吗?
sizeof
is a C keyword. It returns the size in a type named size_t
. However, size_t
is not a keyword, but is defined primarily in stddef.h
and probably other C standard header files too.
Consider a scenario where you want to create a C program which does not include any C standard headers or libraries. (Like for example, if you are creating an OS kernel.) Now, in such code, sizeof
can be used (it is a C keyword, so it is a part of the language), but the type that it returns (size_t
) is not available!
Does not this signify some kind of a problem in the C standard specification? Can you clarify this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
它实际上并不返回 size_t 类型的值,因为 size_t 本身不是具体类型,而是未指定的内置类型的 typedef。 Typedef 标识符(例如 size_t)完全等同于它们各自的基础类型(并在编译时转换为它们)。 如果 size_t 在您的平台上定义为 unsigned int,则 sizeof 在您的系统上编译时将返回 unsigned int。 size_t 只是维护可移植性的一种便捷方法,如果您通过名称显式使用它,则只需将其包含在 stddef.h 中。
It does not literally return a value of type size_t since size_t is not a concrete type in itself, but rather a typedef to an unspecified built-in type. Typedef identifiers (such as size_t) are completely equivalent to their respective underlying types (and are converted thereto at compile time). If size_t is defined as an unsigned int on your platform, then sizeof returns an unsigned int when it is compiled on your system. size_t is just a handy way of maintaining portability and only needs to be included in stddef.h if you are using it explicitly by name.
sizeof
是一个关键字,因为尽管它的名称和用法不同,但它是一个运算符,例如+
或=
或 < code>< 而不是像printf()
或atoi()
或fgets() 这样的函数代码>. 很多人忘记(或者只是不知道)
sizeof
实际上是一个运算符,并且总是在编译时而不是在运行时解析。C 语言不需要
size_t
就成为可用的、一致的语言。 这只是标准库的一部分。 C语言需要所有运算符。 如果 C 使用关键字plus
代替+
来添加数字,则可以将其设为运算符。此外,我将
size_t
半隐式重铸为unsigned int
(以及常规int
),但 Kernighan 和 Ritchie 有一天会打击我为此)一直。 如果您愿意,您可以将sizeof
的返回类型分配给 int,但在我的工作中,我通常只是将其直接传递给malloc()
或其他东西。sizeof
is a keyword because, despite it's name and usage, it is an operator like+
or=
or<
rather than a function likeprintf()
oratoi()
orfgets()
. A lot of people forget (or just don't know) thatsizeof
is actually an operator, and is always resolved at compile-time rather than at runtime.The C language doesn't need
size_t
to be a usable, consistent language. That's just part of the standard library. The C language needs all operators. If, instead of+
, C used the keywordplus
to add numbers, you would make it an operator.Besides, I do semi-implicit recasting of
size_t
s tounsigned int
s (and regularint
s, but Kernighan and Ritchie will someday smite me for this) all the time. You can assign the return type of asizeof
to an int if you like, but in my work I'm usually just passing it straight on to amalloc()
or something.C 标准中的一些头文件是为独立环境定义的,即适合在操作系统内核中使用。 它们不定义任何函数,仅定义和 typedef。
它们是 float.h、iso646.h、limits.h、stdarg.h、stdbool.h、stddef.h 和 stdint.h。
在操作系统上工作时,从这些标头开始并不是一个坏主意。 拥有它们可以使内核中的许多事情变得更容易。 特别是 stdint.h 将变得很方便(uint32_t 等)。
Some headers from the C standard are defined for a freestanding environment, i.e. fit for use e.g. in an operating system kernel. They do not define any functions, merely defines and typedefs.
They are float.h, iso646.h, limits.h, stdarg.h, stdbool.h, stddef.h and stdint.h.
When working on an operating system, it isn't a bad idea to start with these headers. Having them available makes many things easier in your kernel. Especially stdint.h will become handy (uint32_t et al.).
查看 C 的托管实现和独立 C 实现之间的区别。 独立 (C99) 实现需要提供标头:
><
<
这些标头根本不定义任何函数。 它们定义了部分特定于编译器的语言(例如,),但它们可以在不实际作为完整关键字构建到语言中的情况下进行处理。
中的offsetof
宏,以及
中的变量参数列表宏和类型code>这意味着即使在您假设的内核中,您也应该期望 C 编译器提供这些标头和任何底层支持函数 - 即使您提供了其他所有内容。
Look up the difference between a hosted implementation of C and a freestanding C implementation. The freestanding (C99) implementation is required to provide headers:
<float.h>
<iso646.h>
<limits.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
These headers do not define any functions at all. They define parts of the language that are somewhat compiler specific (for example, the
offsetof
macro in<stddef.h>
, and the variable argument list macros and types in<stdarg.h>
), but they can be handled without actually being built into the language as full keywords.This means that even in your hypothetical kernel, you should expect the C compiler to provide these headers and any underlying support functions - even though you provide everything else.
我认为
size_t
不是关键字的主要原因是:例如,在讨论 C++ 标准的下一个主要修订版时,Stroustrup 是这样说的:
I think that the main reasons that
size_t
is not a keyword are:For example, in discussing the next major revision of the C++ standard, Stroustrup had this to say:
没有理由不包含 stddef.h,即使您正在处理内核 - 它定义了任何代码都需要的特定编译器的类型大小。
另请注意,几乎所有 C 编译器都是自编译的。 因此,sizeof 运算符的实际编译器代码将使用 size_t 并引用与用户代码相同的 stddef.h 文件。
There is no reason not to include stddef.h, even if you are working on a kernel - it defines type sizes for your specific compiler that any code will need.
Note also that almost all C compilers are self-compiled. The actual compiler code for the sizeof operator will therefore use size_t and reference the same stddef.h file as does user code.
来自 MSDN:
即使您没有可用/包含的 stddef.h 并且不知道 size_t,使用 sizeof 您也可以获取相对于 char 的对象的大小。
From MSDN:
Even if you don't have stddef.h available/included and don't know about size_t, using sizeof you can get the size of objects relative to char.
size_t 实际上是一种类型 - 通常是无符号整数。 Sizeof 是一个给出类型大小的运算符。 sizeof 返回的类型实际上是特定于实现的,而不是 C 标准。 它只是一个整数。
编辑:
需要明确的是,您不需要 size_t 类型即可使用 sizeof。 我认为您正在寻找的答案是 - 是的,这是不一致的。 不过,没关系。实际上,您仍然可以正确使用 sizeof,而无需头文件中的 size_t 定义。
size_t is actually a type - often an unsigned int. Sizeof is an operator that gives the size of a type. The type returned by sizeof is actually implementation-specific, not a C standard. It's just an integer.
Edit:
To be very clear, you do not need the size_t type in order to use sizeof. I think the answer you're looking for is - Yes, it is inconsistent. However, it doesn't matter. You can still practically use sizeof correctly without having a size_t definition from a header file.
size_t 不一定是关键字。 不同的体系结构通常具有不同的整数类型大小。 例如,如果 64 位机器没有决定将 int 设为 64 位数据类型,则可能会将 unsigned long long 作为 size_t 。
如果将 sizeof 设置为编译器的内置类型,那么它将剥夺进行交叉编译的能力。
另外,sizeof 更像是一个神奇的编译时宏(想想 c++ 模板),这解释了为什么它是一个关键字而不是定义的类型。
size_t is not a keyword by necessity. Different architectures often have different sizes for integral types. For example a 64 bit machine is likely to have an unsigned long long as size_t if they didn't decide to make int a 64 bit datatype.
If you make sizeof a builtin type to the compiler, then it will take away the power to do cross compilation.
Also, sizeof is more like a magic compile time macro (think c++ template) which explains why it is a keyword instead of defined type.
原因很简单,因为它不是基本类型。 如果您查找 C 标准,您会发现基本类型包括
int
、char
等,但不包括size_t
。 为什么这样? 正如其他人已经指出的那样,size_t 是一种特定于实现的类型(即能够保存任何对象的“C 字节”大小的类型)。另一方面,
sizeof
是一个(一元)运算符。 所有运算符都是关键字。The simple reason is because it is not a fundamental type. If you look up the C standard you will find that fundamental types include
int
,char
etc but notsize_t
. Why so? As others have already pointed out,size_t
is an implementation specific type (i.e. a type capable of holding the size in number of "C bytes" of any object).On the other hand,
sizeof
is an (unary) operator. All operators are keywords.