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(
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.
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; }