size_t和std :: size_t之间的区别


139

之间有什么区别size_tstd::size_t,当他们要使用,任何其他差异化功能在他们的声明,其中条款?


我想知道C ++规范是否将std :: size_t链接到C size_t类型。
Doug T.

看到类似的问题:链接
Mankarse 2011年

Answers:


88

C size_t和C ++ std::size_t都相同。

在C中,它是<stddef.h>在C ++中定义的,在C ++中,其定义<cstddef>与C头相同(请参见下面的引号)。其定义为无符号整数类型的的结果的的的sizeof运算符。

C标准在§17.7/ 2中说,

为size_t其是无符号整数类型的的结果的的的sizeof操作者

C ++ Standard cstddef在§18.1/ 3中说(关于标题),

内容与标准C库标头相同,但有以下更改

是的,两者都是一样的。唯一的区别是C ++ size_tstd名称空间中定义。

另请注意,上面的行还显示了“进行了以下更改” ,这并不是指size_t。它宁可指的是C ++对语言(C中不存在)所做的新添加(大部分),这些添加也定义在同一标头中。


Wikipedia具有有关size_t的范围和存储大小的非常好的信息:

size_t的范围和存储大小

size_t 的实际类型与 平台有关;一个常见的错误 是假定size_t与unsigned int相同,例如,当从32位架构转换为64位架构时,可能会导致编程错误[3] [4]。

根据1999 ISO C标准(C99),size_t是至少16位的无符号整数类型。

您可以在Wikipedia的此页面上阅读其余内容。


那就是另一个问题,如果STL已经通过C(cstddef)导入了size_t,为什么它又有了自己的另一个版本?
Alok保存

43
@Als:严格来说,如果size_t不使用using namespace std;或,这是错误的using std::size_t;。但是,大多数编译器都允许它,并且标准专门允许他们允许它(§D.5/ 3)。
Potatoswatter

9
@Potatoswatter:当然不能既是错误又是标准中明确允许的内容?如果符合标准,那不是错误!
本·海默斯

8
@BenHymers该标准指定标准标头声明的内容,不允许它们声明任何其他非保留名称。标头<cstddef>可以声明也可以不声明::size_t,因此您不能依赖它的存在或不存在,除非明确包含<stddef.h>了C库中另一个保证可以声明它的标头。
Potatoswatter

4
@Potatoswatter:啊,我明白你的意思了!我一定在一句话中被太多“允许”弄糊涂了。我仍然认为您的第一句话太强烈了。就像您刚才所说的,::size_t例如存在于中<stddef.h>,因此您不必总是用来限定它std::
Ben Hymers

16

从C ++ 03“ 17.4.3.1.4类型”开始:

对于标准C库中的每个T类型(脚注169),类型:: T和std :: T保留给实现,并且在定义时:: T必须与std :: T相同。

和脚注169:

这些类型为clock_t,div_t,FILE,fpos_t,lconv,ldiv_t,mbstate_t,ptrdiff_t,sig_atomic_t,size_t,time_t,tm,va_list,wctrans_t,wctype_t和wint_t。


因此,可移植代码不应该依赖于std::T所定义的变体吗?
Mankarse 2011年

5
@Mankarse:如果仅包含相应标头的C版本,则不应依赖于它们的定义。如果你#include <stddef.h>那么std::size_t可能会或可能无法使用。如果您#include <cstddef>当时std::size_t有空,但size_t可能没有。
丹尼斯·齐克福斯

4
@Mankarse:对面。标头的C ++版本必须在其中定义它们,std::并且该段落说,它也可以在顶级名称空间中定义它们,如果是,则必须在std::和顶级中相同地定义它们。大多数编译器仅包含C头并将名称导入std::,因此最终两个符号中都定义了符号。
1月Hudec

4
就个人而言,我从不理会<cxxxxx>标头或std::来自C岸的标识符的变体。我坚持使用<xxxxx.h>标准C标头-从来没有问题。因此,我会使用<stddef.h>并且size_t永远不会考虑std::size_t;实际上,我永远不会想到存在(或可能存在)std::size_t
Michael Burr

12

std :: size_t实际上是stddef.hsize_t

cstddef提供以下内容:

#include <stddef.h>
namespace std 
{
  using ::ptrdiff_t;
  using ::size_t;
}

...有效地将先前的定义引入了std名称空间。


正如纳瓦兹(Nawaz)所指出的,实际上是相反的情况。你不能包括<cstddef>期望得到::size_t,但是如果你包括<stddef.h>你将会得到std::size_t
MSalters 2011年

4
@MSalters,我不关注。包括<stddef.h>只会得到你::size_t
hamper

2
那就是您的实现中的错误。
MSalters 2011年

4
@MSalters,我不太了解。不应该反过来吗?<cstddef>来自C ++,因此应该在std :: *中定义内容?另一方面,在C标头(如stddef.h)中,我只希望使用C类型,即:: size_t。
Ela782 2014年

11
@MSalters,因为C ++ 11不正确。如果您包括在内,<cstddef>那么std::size_t您一定会得到保证,而且您也可能会得到::size_t(但不能保证)。如果包括在内,<stddef.h>您肯定::size_t会得到,而且您也可能会得到std::size_t(但不保证)。它在C ++ 03中有所不同,但实际上无法实现,并已作为缺陷修复。
Jonathan Wakely
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.