`sizeof` *真的*计算为`std :: size_t`吗? 它可以?

采取以下标准通道:

[C++11: 5.3.3/6]: sizeofsizeof...的结果是std::size_ttypes的常量。 [注: std::size_t是在标准头文件<cstddef> (18.2)中定义的。 – 注意]

现在:

[C++11: 18.2/6]:typessize_t是一个实现定义的无符号整数types,它足够大以包含任何对象的字节大小。

当然,这段文字并不要求size_t是一个用typedef定义的types别名,但是由于它明确声明是由标准头文件<cstddef> ,所以我认为我们可以认为没有包含<cstddef>删除任何保证size_t应可用于程序。

但是,根据第一个引用,我们可以不pipe获取std::size_ttypes的expression式。

我们实际上可以certificate这两个事实 :

 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' } 

std::size_t对程序不可见,但是sizeof(0)仍然给我们一个? 真?

所以说5.3.3/6是否有缺陷 ,而且它实际上和std::size_tparsing为“相同的types”,而不是 std::size_t本身呢?

当然,如果std::size_t是一个types别名,那么这两个是一样的,但是,再次,实际上这是不需要的。

不要混淆地图的领土。

types可以用types名来命名。 这些types名称可以是内置的,它们可以是用户定义的types,或者甚至可以是template参数,并根据实例化引用多种不同的types。

但是名字不是那种types。 显然,标准并不要求所有types都有名字,典型的struct {}是一个没有名字的types。

std::size_t是一个typename。 它命名sizeof(expression)返回的types。

编译器可以有一个types的规范名称 – __size_t将是一个唯一的内置规范types名称的方法。

在该子句中,标准保证不pipesizeof(expression)的types是什么,一旦你包含了#include <cstddef> ,名字std::size_t现在就是指那个types。

在标准中,它们是指名称的types。 他们不会说“这个types名称所指的types”,而只是说“types$ NAME $”。 如果需要,编译器可以决定int__int_32_fast另一个名字,标准也不会有任何异议。

同样的事情发生在std::nullptr_tstd::initializer_list<Ts>std::type_info :这些types的variables的使用并不总是要求为你提供这些types名称的头文件包含在你的程序中。

传统的C / C ++内置types都具有不需要头的规范名称。 缺点是这会破坏现有代码,因为全局范围中的新types名称与其他标识符相冲突。

通过使用“无名types”,可以通过包含头文件来获取名称,我们可以避免这个问题。

该标准只是要求sizeof(expr)的types与std::size_t是相同的types。 没有要求使用sizeof(expr)使名称std::size_t可用,并且因为std::size_t只是命名内置整型types之一,所以没有任何问题。

据我所知,这个标准的段落需要下面的expression式:

 typeid(sizeof(0)) == typeid(std::size_t) 

将永远产生true 。 如果使用实际标识符std::size_t::size_t或任何其他别名/ typedef将是不相关的,只要按照std::typeinfo::operator==()保留types的标识。

语言的其他地方出现同一types身份问题。 例如,在我的64位机器中,以下代码由于函数重定义而无法编译:

 #include <cstddef> void foo(std::size_t x) {} void foo(unsigned long x) {} 

是。

sizeof产生的sizeof是一些无符号的整数types; 该实现定义了它是哪一个。

例如,在某些特定的实现中, sizeofexpression式的types可能是unsigned long

std::size_t ,如果它是一个typedef ,只不过是unsigned long的替代名称。 所以这两个陈述:

sizeof ...的types是一个unsigned longtypes的常量

sizeof ...的types是std::size_ttypes的常量

对于这个实现来说,完全一样。 unsigned longtypes和std::size_ttypes是相同的types。 不同之处在于后者对于所有(符合)实现都是准确的,其中std::size_t可能是unsigned int或其他一些无符号types的别名。

就编译器而言, sizeof产生unsigned longtypes的结果; 编译器(而不是运行时库)不需要知道名称size_t

这一切都假定std::size_t (或只是size_t如果你在谈论C)是一个typedef。 这不是在C或C ++标准中阐明的。 尽pipe如此,通过将size_t为typedef,实现可以直接符合标准的要求。 我不相信有任何其他便携式的方式来满足这些要求。 (它不能是一个macros或一个实现定义的关键字,因为这会侵犯用户的名字空间,并且一个macros不会在std名字空间范围内)。编译器可以使size_t实现特定的结构,而不是一个typedef,但是由于typedef工作得很好,这样做没有意义。 这将是很好,恕我直言,如果标准规定size_t是一个typedef。

(一个不相干的问题:真正的问题是标准把结果称为“常量”,在ISO C中,“常数”是一个标记,比如一个整数字面量。据我所知,C ++不会“定义名词“常量”,但它确实引用了ISO C的定义, sizeof ...是一个常量expression式 ;它不是一个常量 ,调用结果“常量值”是合理的。

这是相同的types,但你必须包括该头来使用它。