By jwfearn


2008-10-26 01:55:05 8 Comments

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 );
}

8 comments

@mloskot 2009-08-06 10:23:48

std::size_t n = sizeof( long );

Actually, you haven't asked what specifically seems to be a bad practice int the above. Use of size_t, qualification with std namespace,...

As the C++ Standard says (18.1), size_t is a type defined in the standard header . I'd suggest to drop any thoughts and impressions about possible inheritance from C language. C++ is a separate and different language and it's better to consider it as such. It has its own standard library and all elements of C++ Standard Library are defined within namespace std. However, it is possible to use elements of C Standard Library in C++ program.

I'd consider including as a dirty hack. The C++ Standard states that the content of headers is the same or based on corresponding headers from the C Standard Library, but in number of cases, changes have been applied. In other words, it's not a direct copy & paste of C headers into C++ headers.

size_t is not a built-in type in C++. It is a type defined to specify what kind of integral type is used as a return type of sizeof() operator, because an actual return type of sizeof() is implementation defined, so the C++ Standard unifies by defining size_t.

would the following program (with no includes) be expected to compile on all C++ compilers?

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

The C++ Standard says (1.4):

The names defined in the library have namespace scope (7.3). A C ++ translation unit (2.1) obtains access to these names by including the appropriate standard library header (16.2).

The size_t is a name defined within std namespace, so every program that uses this name should include corresponding header, in this case.

Next, the 3.7.3 chapter says:

However, referring to std, std::bad_alloc, and std::size_t is ill-formed unless the name has been declared by including the appropriate header.

Given that, program using size_t but not including header is ill-formed.

@Michael S 2009-05-11 22:48:22

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.

@Billy ONeal 2012-05-09 16:56:51

::size_t doesn't make sense in C, which has no namespaces.

@Martin 2009-04-16 04:30:09

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;

}

@Michael Dorst 2013-03-12 10:49:27

So GNU defines it that way, does that mean that all compilers do? Does the standard say it must be so?

@Johannes Schaub - litb 2008-11-12 04:18:55

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.

@Darryl 2009-11-19 00:39:26

Absolutely the best answer here. It's based on the standard instead of a particular compiler. It answers the original question without straying down tangents.

@Lee Louviere 2011-10-31 19:32:21

Another reason to not use using namespace std

@Lightness Races in Orbit 2012-01-13 12:16:11

@Darryl: To be fair, all the older answers did so too.

@Eugene Shapovalov 2015-08-13 15:37:55

C++11 standard says that cstddef should define everything that stddef.h does, including ::size_t. So I see no reason to use std::size_t instead of size_t. See "18.2.2: <—Āstddef> The contents are the same as the Standard C library header <stddef.h>, with the following changes..." and here is nothing about absence of ::size_t.

@Johannes Schaub - litb 2015-08-13 17:59:39

@eugene the answer is c++03 specific. Feel free to extend itto cover C++11. One advantage is that your code stays c++03 conforming if that is one of the goals.

@M.M 2017-05-31 04:49:17

@EugeneShapovalov I am unconvinced by that quote: if we go with your interpretation, then it never says that std::size_t should be defined! I guess that even that sentence is still meant to be taken in conjunction with [contents]/2 which says "All library entities [...] are defined within the namespace std..."

@fizzer 2008-10-26 11:12:02

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.

@fizzer 2008-10-26 11:32:00

Some explanation of the downvote would be polite. The answer is correct & on topic.

@Don Wakefield 2008-10-26 15:44:25

I don't know who voted you down. Your observation is very much on point to the original question.

@cic 2008-10-26 19:22:20

I voted you down, mainly because there is a non-deprecated way of doing this: using-declarations, i.e. using std::size_t, and you didn't mention this as a better alternative. :-)

@Don Wakefield 2008-10-27 15:49:00

Except I think @fizzer was explaining how you might end up with size_t in the global namespace in your C++ program, not making a recommendation that you do so.

@Lightness Races in Orbit 2012-01-13 12:17:23

You didn't really answer the question. You answered a related question.

@Brian R. Bondy 2008-10-26 01:57:14

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.

@jwfearn 2008-10-26 02:16:39

That makes sense. Do you know if "::size_t" or "std::size_t" (or perhaps both) are part of the language spec?

@ypnos 2008-10-26 02:18:27

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.

@Don Wakefield 2008-10-26 02:21:18

Section 17.4.1.2 of the C++ standard, paragraph 4, states that:

"In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std."

This includes items found in headers of the pattern cname, including cstddef, which defines size_t.

So std::size_t is in fact correct.

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2200547 View
  • 4247 Score
  • 1 Answer
  • Tags:   c++ c++-faq

37 Answered Questions

8 Answered Questions

[SOLVED] unsigned int vs. size_t

  • 2008-09-25 07:00:03
  • Rob
  • 193573 View
  • 474 Score
  • 8 Answer
  • Tags:   c++ c size-t

15 Answered Questions

[SOLVED] How can I profile C++ code running on Linux?

  • 2008-12-17 20:29:24
  • Gabriel Isenberg
  • 480230 View
  • 1690 Score
  • 15 Answer
  • Tags:   c++ unix profiling

10 Answered Questions

21 Answered Questions

[SOLVED] What is the "-->" operator in C++?

36 Answered Questions

[SOLVED] Why is "using namespace std;" considered bad practice?

12 Answered Questions

[SOLVED] What is size_t in C?

  • 2010-03-31 05:51:55
  • Vijay
  • 658459 View
  • 573 Score
  • 12 Answer
  • Tags:   c int size-t

11 Answered Questions

[SOLVED] What does the explicit keyword mean?

Sponsored Content