size_t 和 std::size_t 之间的区别

Posted

技术标签:

【中文标题】size_t 和 std::size_t 之间的区别【英文标题】:Difference between size_t and std::size_t 【发布时间】:2011-04-28 04:41:41 【问题描述】:

size_tstd::size_t 在声明的位置、应在何时使用以及任何其他区别特性方面有何区别?

【问题讨论】:

我很想知道 C++ 规范是否将 std::size_t 链接到 C size_t 类型。 查看类似问题:link 【参考方案1】:

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

在 C 中,它在 <stddef.h> 中定义,而在 C++ 中,它在 <cstddef> 中定义,其内容与 C 标头相同(参见下面的引用)。其定义为 sizeof 运算符的result无符号整数类型

C 标准在 §17.7/2 中说,

size_t 是 sizeof 运算符的结果无符号整数类型

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

内容与标准C库头文件相同,有如下改动

是的,两者都是一样的; 唯一的区别是C++在std命名空间中定义了size_t

还请注意,上面的行还说“有以下更改”,这并不是指size_t。它更确切地说是指 C++ 对语言(C 中不存在)所做的新添加(大部分),这些添加也定义在同一个标​​题中。


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

size_t的范围和存储大小

size_t 的实际类型是 平台相关常见错误 是假设 size_t 与 unsigned int,这可能导致 移动时出现编程错误,[3][4] 从 32 位到 64 位架构,适用于 例子。

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

其余的您可以从***的this page 阅读。

【讨论】:

这就引出了另一个问题,如果 STL 已经通过 C (cstddef) 导入了 size_t,为什么它又要有自己的另一个版本? @Als: 严格来说,size_t 不带using namespace std;using std::size_t; 是错误的。但是,大多数编译器都允许它,标准特别允许它们允许它(§D.5/3)。 @Potatoswatter:当然不能既是错误又不能在标准中明确允许?如果符合标准,那就不是错误! @BenHymers 该标准规定了标准标头声明的内容,并且不允许它们声明任何其他非保留名称。标头 <cstddef> 可能会或可能不会声明 ::size_t,因此您不能依赖它存在或不存在,除非特别包含 <stddef.h> 或 C 库中保证声明它的另一个标头。 @Potatoswatter:啊,我明白你的意思了!我一定是被一句话中的太多“允许”弄糊涂了。不过,我仍然认为您的第一条评论太强烈了;正如您刚才所说,::size_t 存在于例如<stddef.h> 中,因此您并不总是需要使用std:: 对其进行限定。【参考方案2】:

来自 C++03“17.4.3.1.4 类型”:

对于标准 C 库(脚注 169)中的每个类型 T,类型 ::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:你不应该依赖它们被定义如果你只包括相应标题的C版本。如果您 #include <stddef.h>std::size_t 可能可用也可能不可用。如果您 #include <cstddef>std::size_t 可用,但 size_t 可能不可用。 @Mankarse:相反。标头的 C++ 版本必须在 std:: 中定义它们,并且该段落说它也可以在***命名空间中定义它们,如果是这样,它必须在 std:: 和***名称空间中相同地定义它们。大多数编译器只包含 C 头文件并将名称导入到std::,因此这些符号最终都会在两者中定义。 就个人而言,我从不关心来自 C 岸的 标头或标识符的 std:: 变体。对于标准 C 头文件,我坚持使用 <xxxxx.h> - 这从来都不是问题。所以,我会使用<stddef.h>size_t 并且永远不会再考虑std::size_t;事实上,我从未想过有(或可能有)std::size_t【参考方案3】:

std::size_t其实就是stddef.hsize_t

cstddef 给出以下内容:

#include <stddef.h>
namespace std 

  using ::ptrdiff_t;
  using ::size_t;

...有效地将先前的定义带入 std 命名空间。

【讨论】:

正如 Nawaz 指出的那样,实际上恰恰相反。您不能包含&lt;cstddef&gt; 并期望获得::size_t,但如果您包含&lt;stddef.h&gt;,您将获得std::size_t @MSalters,我不关注。包括&lt;stddef.h&gt; 只会得到::size_t 那是你的实现中的一个错误。 @MSalters,我不太明白。不应该反过来吗? 来自 C++,因此应该在 std::*?另一方面,在像 stddef.h 这样的 C 头文件中,我只期望 C 类型,即 ::size_t。 @MSalters,因为 C++11 不准确。如果您包含&lt;cstddef&gt;,则保证您会获得std::size_t,并且您可能还会获得::size_t(但不能保证)。如果您包含&lt;stddef.h&gt;,那么您肯定会获得::size_t,并且您可能还会获得std::size_t(但不能保证)。它在 C++03 中有所不同,但实际上无法实现并作为缺陷修复。

以上是关于size_t 和 std::size_t 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

“std::size_t”在 C++ 中有意义吗?

std::size_t 与 size_type 作为参数和函数返回类型

std::size_t 还是 std::vector<Foo>::size_type?

没有匹配函数调用‘std::set<unsigned int>::insert(std::size_t&)

如何定义自定义跨平台 size_t 类型?

将 opengl Window 转换为 std::size_t 并再次在 Linux 中有效,但在 OS X 中无效