Does “std::size_t” make sense in C++?

2019-01-07 08:23发布

In some code I've inherited, I see frequent use of size_t with the std namespace qualifier. For example:

std::size_t n = sizeof( long );

It compiles and runs fine, of course. But it seems like bad practice to me (perhaps carried over from C?).

Isn't it true that size_t is built into C++ and therefore in the global namespace? Is a header file include needed to use size_t in C++?

Another way to ask this question is, would the following program (with no includes) be expected to compile on all C++ compilers?

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

标签: c++ size-t
8条回答
对你真心纯属浪费
2楼-- · 2019-01-07 08:23

size_t is not built into C++. And it is not defined by default. This one doesn't compile with GCC:

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

That said, size_t is part of POSIX and if you use only basic things like <cstdlib>, you will likely end up having it defined.

You could argue that std::size_t is the C++ equivalent of size_t. As Brian pointed out, std:: is used as namespace to avoid setting global variables which don't fit everybody. It's just like std::string, which could also have been defined in the root namespace.

查看更多
戒情不戒烟
3楼-- · 2019-01-07 08:24

Sometimes other libraries will define their own size_t. For example boost. std::size_t specifies that you definitely want the c++ standard one.

size_t is a c++ standard type and it is defined within the namespace std.

查看更多
Bombasti
4楼-- · 2019-01-07 08:29

I think the clarifications are clear enough. The std::size_t makes good sense in C++ and ::size_t make (at least) good sense in C.

However a question remain. Namely whether it is safe to assume that ::size_t and std::size_t are compatible?

From a pure typesafe perspective they are not necessarily identical unless it is defined somewhere that they must be identical.

I think many are using something a 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 ) 
{
  ...
}

So in the header you defintely use the ::size_t while in the source file you'll use std::size_t. So they must be compatible, right? Otherwise you'll get a compiler error.

/Michael S.

查看更多
放荡不羁爱自由
5楼-- · 2019-01-07 08:30

There seems to be confusion among the stackoverflow crowd concerning this

::size_t is defined in the backward compatibility header stddef.h . It's been part of ANSI/ISO C and ISO C++ since their very beginning. Every C++ implementation has to ship with stddef.h (compatibility) and cstddef where only the latter defines std::size_t and not necessarily ::size_t. See Annex D of the C++ Standard.

查看更多
我想做一个坏孩纸
6楼-- · 2019-01-07 08:35

You can get size_t in the global namespace by including, for example, <stddef.h> instead of <cstddef>. I can't see any obvious benefit, and the feature is deprecated.

查看更多
仙女界的扛把子
7楼-- · 2019-01-07 08:38

The GNU compiler headers contain something like

typedef long int __PTRDIFF_TYPE__;
typedef unsigned long int __SIZE_TYPE__;

Then stddef.h constains something like

typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;

And finally the cstddef file contains something like

#include <stddef.h>

namespace std {

  using ::ptrdiff_t;
  using ::size_t;

}

I think that should make it clear. As long as you include <cstddef> you can use either size_t or std::size_t because size_t was typedefed outside the std namespace and was then included. Effectively you have

typedef long int ptrdiff_t;
typedef unsigned long int size_t;

namespace std {

  using ::ptrdiff_t;
  using ::size_t;

}
查看更多
登录 后发表回答