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

时间:2008-10-26 01:55:05

标签: c++ size-t

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

std::size_t n = sizeof( long );

当然,编译并运行良好。但对我来说这似乎是不好的做法(也许从C继续?)。

size_t是否构建在C ++中,因此在全局命名空间中是不是真的?是否需要在C ++中使用size_t包含头文件?

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

size_t foo()
{
    return sizeof( long );
}

8 个答案:

答案 0 :(得分:129)

对于这个

,stackoverflow人群之间似乎存在混淆

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

答案 1 :(得分:41)

C ++标准第17.4.1.2节第4段规定:

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

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

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

答案 2 :(得分:13)

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

答案 3 :(得分:4)

size_t没有内置到C ++中。它没有默认定义。这个不用GCC编译:

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

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

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

答案 4 :(得分:4)

std::size_t n = sizeof( long );

实际上,你还没有问过上面有什么具体的坏习惯。使用size_t,使用std命名空间进行限定,......

正如C ++标准所说(18.1),size_t是标准头中定义的类型。我建议放弃有关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但不包括标题的程序格式不正确。

答案 5 :(得分:2)

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

size_t是c ++标准类型,它在名称空间std。

中定义

答案 6 :(得分:2)

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 <stddef.h>

namespace std {

  using ::ptrdiff_t;
  using ::size_t;

}

我认为应该说清楚。只要你包含&lt; cstddef&gt;你可以使用size_t或std :: size_t,因为size_t是在std命名空间之外的typedefed然后包含的。实际上你有

typedef long int ptrdiff_t;
typedef unsigned long int size_t;

namespace std {

  using ::ptrdiff_t;
  using ::size_t;

}

答案 7 :(得分:2)

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

但问题仍然存在。即假设::size_tstd::size_t兼容是否安全?

从纯粹的类型安全角度来看,它们不一定相同,除非它被定义为必须相同的地方。

我认为很多人正在使用la:

----
// 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。{{1}}。所以它们必须兼容,对吗?否则你会收到编译错误。

/ Michael S.