`sizeof` *真的*计算为`std :: size_t`?它可以? [英] Does `sizeof` *really* evaluate to a `std::size_t`? Can it?
问题描述
采取以下标准程序:
[C ++ 11:5.3.3 / 6]:
sizeof
和的结果是sizeof ...
是类型std :: size_t
。< cstddef>
在标准标题中定义std :: size_t
(18.2)。 - end note]
[C++11: 5.3.3/6]:
The result ofsizeof
andsizeof...
is a constant of typestd::size_t
. [ Note:std::size_t
is defined in the standard header<cstddef>
(18.2). —end note ]
现在:
[C ++ 11:18.2 / 6]:
类型 size_t
授予,通过不会有任何对象的大小要求 size_t
是用 typedef
定义的类型别名,但是因为它明确声明由标准头< cstddef>
,我想我们可以采取未能包括< cstddef>
size_t
可用于程序。
Granted, the passage doesn't require that size_t
is a type alias defined with typedef
, but since it's explicitly stated to be made available by the standard header <cstddef>
, I think we can take as read that failing to include <cstddef>
should remove any guarantee that size_t
shall be available to a program.
但是,根据第一个引号, std :: size_t
的表达式。
However, according to that first quote, we can regardless obtain an expression of type std::size_t
.
int main()
{
typedef decltype(sizeof(0)) my_size_t;
my_size_t x = 0; // OK
std::size_t y = 1; // error: 'size_t' is not a member of 'std'
}
code> std :: size_t 对程序不可见,但 sizeof(0)
仍然给我们一个?真的吗?
std::size_t
is not visible to the program, but sizeof(0)
still gives us one? Really?
因此, 5.3.3 / 6
缺陷,并且它实际上具有与任何 std :: size_t
解析为相同的类型,但不是 std :: size_t 本身?
Is it therefore not correct to say that 5.3.3/6
is flawed, and that it actually has "the same type as whatever std::size_t
resolves to", but not std::size_t
itself?
当然,两者是一样的,如果 std :: size_t
是一个类型别名,但是,实际上并不需要这么做。
Sure, the two are one and the same if std::size_t
is a type alias but, again, nowhere is this actually required.
推荐答案
不要混淆地图。
类型可以通过类名命名。这些类型名可以是内置的,它们可以是用户定义的类型,或者甚至可以是 template
参数,并且根据实例化引用多个不同类型。
Types can be named by typenames. These typenames can be built-in, they can be user-defined types, or they could even be template
parameters and refer to multiple different types depending on the instantiation.
但是名称不是类型。显然,标准并不要求所有类型都有名称 - 经典的 struct {}
是一个没有名称的类型。
But the names are not the types. Clearly standard does not mandate that all types have names -- the classic struct {}
is a type without a name.
std :: size_t
是类型名称。它命名 sizeof(expression)
返回的类型。
std::size_t
is a typename. It names the type that sizeof(expression)
returns.
编译器可以有一个规范名称类型 - - __ size_t
将是一种具有唯一内置规范类型名称的方法。
The compiler could have a canonical name for the type -- __size_t
would be one way for it to have a unique built-in canonical typename.
标准保证无论 sizeof(expression)
的类型是什么,一旦你 #include< cstddef>
std :: size_t
现在指的是该类型。
The standard guarantees in that clause that whatever the type of sizeof(expression)
is, once you #include <cstddef>
, the name std::size_t
now refers to that type.
在标准中,它们按名称引用类型。他们不说这个类型名称引用的类型,而只是说类型$ NAME $。编译器可以决定 int
是 __ int_32_fast
的另一个名称,如果它想,并且标准将没有反对。
In the standard, they refer to types by names. They do not say "the type that this typename refers to", but simply say "the type $NAME$". The compiler could decide that int
is another name for __int_32_fast
if it wanted to, and the standard would have no objection either.
同样的事情发生在 std :: nullptr_t
和 std :: initializer_list< Ts>
和 std :: type_info
:使用这些类型的变量并不总是需要为这些类型提供名称的头包含在您的程序中。
This same thing happens with std::nullptr_t
and std::initializer_list<Ts>
and std::type_info
: use of variables of those types does not always require that the header that provides you with a name for those types be included in your program.
传统的C / C ++内置类型都具有不需要标题的规范名称。缺点是,这打破了现有代码,因为全局范围中的新类型会与其他标识符冲突。
The traditional C/C++ built-in types all had canonical names that did not require a header. The downside is that this breaks existing code, as new typenames in the global scope collide with other identifiers.
通过使用无名类型,您可以获取名称他们通过包含头文件,我们避免了这个问题。
By having "nameless types", where you can get a name for them via including a header file, we avoid that problem.
这篇关于`sizeof` *真的*计算为`std :: size_t`?它可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!