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

Posted

技术标签:

【中文标题】“std::size_t”在 C++ 中有意义吗?【英文标题】:Does "std::size_t" make sense in C++? 【发布时间】:2008-10-26 01:55:05 【问题描述】:

在我继承的一些代码中,我看到size_t 经常与std 命名空间限定符一起使用。例如:

std::size_t n = sizeof( long );

当然,它编译并运行良好。但这对我来说似乎是一种不好的做法(可能是从 C 继承而来的?)。

size_t 不是内置在 C++ 中并因此位于全局命名空间中吗?在 C++ 中使用 size_t 是否需要包含头文件?

问这个问题的另一种方法是,以下程序(包含 no)是否应该在所有 C++ 编译器上编译

size_t foo()

    return sizeof( long );

【问题讨论】:

C 没有命名空间。 它内置在 C++ 中,当你#include 时,它位于命名空间 std。请参阅下面的答案。 这不是“提出这个问题的另一种方式”——这是一个不同的问题:main 返回 int。 【参考方案1】:

*** 人群似乎对此感到困惑

::size_t 在向后兼容标头 stddef.h 中定义。它从一开始就是ANSI/ISO CISO C++ 的一部分。每个 C++ 实现都必须附带 stddef.h(兼容性)和 cstddef,其中只有后者定义 std::size_t 而不一定是 ::size_t。请参阅 C++ 标准的附录 D。

【讨论】:

这里绝对是最好的答案。它基于标准而不是特定的编译器。它回答了最初的问题而没有偏离正线。 另一个不使用using namespace std的理由 @Darryl:公平地说,所有较旧的答案也是如此。 C++11 标准规定 cstddef 应该定义 stddef.h 所做的一切,包括 ::size_t。所以我认为没有理由使用 std::size_t 代替 size_t。请参阅“18.2.2: 内容与标准 C 库头文件 相同,有以下更改......”这里没有关于 ::size_t 的内容。 @eugene 答案是 c++03 特定的。随意扩展它以涵盖 C++11。一个优点是,如果这是目标之一,您的代码将保持符合 c++03。【参考方案2】:

C++ 标准第 17.4.1.2 节第 4 段指出:

“但是,在 C++ 标准库中,声明和定义(在 C 中定义为宏的名称除外)在命名空间 std 的命名空间范围 (3.3.5) 内。”

这包括在模式 cname 的标题中找到的项目,包括定义 size_t 的 cstddef

所以 std::size_t 实际上是正确的。

【讨论】:

【参考方案3】:

您可以在全局命名空间中获得size_t,例如,包括<stddef.h> 而不是<cstddef>。我看不到任何明显的好处,并且该功能已被弃用。

【讨论】:

对否决票的一些解释是礼貌的。答案正确且符合主题。 我不知道是谁投了你的票。您的观察与原始问题非常吻合。 我对你投了反对票,主要是因为有一种不被弃用的方法:使用声明,即using std::size_t,你没有提到这是一个更好的选择。 :-) 除了我认为@fizzer 是在解释你如何可能在你的 C++ 程序的全局命名空间中使用 size_t,而不是建议你 i> 所以。 你没有真正回答这个问题。您回答了一个相关问题。【参考方案4】:

size_t 没有内置在 C++ 中。并且默认情况下没有定义。这个不能用 GCC 编译:

int main(int argc, char** argv) 
size_t size;

也就是说,size_t 是 POSIX 的一部分,如果您只使用 <cstdlib> 之类的基本内容,您最终可能会定义它。

您可以争辩说 std::size_t 是 size_t 的 C++ 等价物。正如布赖恩所指出的,std:: 被用作命名空间以避免设置不适合所有人的全局变量。它就像 std::string 一样,也可以在根命名空间中定义。

【讨论】:

【参考方案5】:
std::size_t n = sizeof( long );

实际上,您还没有问过上面的具体做法是什么。使用 size_t,使用 std 命名空间进行限定,...

正如 C++ 标准 (18.1) 所说, size_t 是在标准 header 中定义的类型。我建议放弃关于可能从 C 语言继承的任何想法和印象。 C++ 是一种独立且不同的语言,最好这样考虑。它有自己的标准库,并且 C++ 标准库的所有元素都在命名空间 std 中定义。但是,可以在 C++ 程序中使用 C 标准库的元素。

我会考虑将其作为一个肮脏的黑客。 C++ 标准规定标头的内容是相同的或基于 C 标准库中的相应标头,但在许多情况下,已应用了更改。换句话说,它不是将 C 头文件直接复制并粘贴到 C++ 头文件中。

size_t 不是 C++ 中的内置类型。它是一种定义类型,用于指定使用哪种整数类型作为 sizeof() 运算符的返回类型,因为 sizeof() 的实际返回类型是实现定义的,所以 C++ 标准通过定义 size_t 来统一。

下面的程序(没有 包括)预计编译 所有 C++ 编译器?

size_t foo()

    return sizeof( long );

C++ 标准说 (1.4):

库中定义的名称具有命名空间范围 (7.3)。 C++ 翻译单元 (2.1) 通过包含适当的标准库头文件 (16.2) 来获得对这些名称的访问权。

size_t 是在 std 命名空间中定义的名称,因此在这种情况下,每个使用此名称的程序都应包含相应的标头。

接下来,3.7.3章节说:

但是,除非通过包含适当的标头来声明名称,否则引用 std、std::bad_alloc 和 std::size_t 是不正确的。

鉴于此,使用 size_t 但不包含标头的程序格式不正确。

【讨论】:

【参考方案6】:

有时其他库会定义自己的 size_t。例如升压。 std::size_t 指定您肯定想要 c++ 标准。

size_t 是一个 c++ 标准类型,它在命名空间 std 中定义。

【讨论】:

这是有道理的。你知道“::size_t”或“std::size_t”(或两者兼有)是语言规范的一部分吗?【参考方案7】:

GNU 编译器头文件包含类似

typedef long int __PTRDIFF_TYPE__;
typedef unsigned long int __SIZE_TYPE__;

然后 stddef.h 包含类似的东西

typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;

最后,cstddef 文件包含类似

#include 命名空间标准 使用 ::ptrdiff_t; 使用 ::size_t;

我认为这应该说清楚。只要您包含 ,您就可以使用 size_t 或 std::size_t 因为 size_t 在 std 命名空间之外进行了类型定义,然后被包含在内。实际上你有

typedef long int ptrdiff_t;
typedef unsigned long int size_t;

命名空间标准

  使用 ::ptrdiff_t;
  使用 ::size_t;


【讨论】:

所以 GNU 是这样定义的,这是否意味着所有编译器都这样做?标准是否规定必须如此?【参考方案8】:

我认为澄清已经足够清楚了。 std::size_t 在 C++ 中很有意义,::size_t 在 C 中(至少)很有意义。

但是还有一个问题。即假设::size_tstd::size_t 兼容是否安全?

从纯粹的类型安全的角度来看,它们不一定相同,除非在某处定义它们必须相同。

我认为很多人都在使用一些东西:

----
// a.hpp 
#include <string>

void Foo( const std::string & name, size_t value );

-----
// a.cpp
#include "a.hpp"

using namespace std;

void Foo( const string & name, size_t value ) 

  ...

因此,在标题中您肯定会使用::size_t,而在源文件中您将使用std::size_t。所以他们一定是兼容的,对吧?否则你会得到一个编译器错误。

/迈克尔·S.

【讨论】:

::size_t 在没有命名空间的 C 中没有意义。

以上是关于“std::size_t”在 C++ 中有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章

size_t 和 std::size_t 之间的区别

如果(!这个)返回; 在 C# 中有意义吗?

是否hreflang attr。在 <base> 中有意义吗?

阴阳延续谜题在打字语言中有意义吗?

在 HTTP/2 中使用图像精灵有意义吗?

在同一个目录中有两个包有意义吗?