I have recently been told that using size_t
as declared in the global namespace is incorrect in C++, ostensibly because size_t
is a C-feature. I looked this up and came across this question on Stack Overflow:
https://stackoverflow.com/questions/5813700/difference-between-size-t-and-stdsize-t
The top answer makes it pretty clear that there isn’t any real difference between size_t
and std::size_t
, but that leaves open the question of style and correctness.
Since I’m programming in C++, is it “wrong” to use a C feature such as size_t
in place of the slightly longer but no better C++-specific std::size_t
?
2
<stddef.h>
is a 100% standard header file in C++, that provides the type ::size_t
.
As a bonus it also is standard in C. Very nice if you’re writing a header file for a library with a C-compatible interface, using #if __cplusplus
/ extern "C" {
.
Note that the usual arguments about namespaces and naming collisions don’t apply, as the Standard allows inclusion of any or all header files to introduce ::size_t
.
The only time that using std::size_t
is “better” than ::size_t
is if you have not included <stddef.h>
(perhaps you have #include <cstddef>
instead).
8
If you care about ‘the law’ as laid out by the offical C++ standard then yes, it is bad to use size_t
.
size_t
(i.e. ::size_t
) can only be reliably included from <stddef.h>
(and its relatives).
<cstddef>
(and its relatives) will only guarantee the inclusion of std::size_t
(i.e. ::std::size_t
), it will not guarantee the inclusion of size_t
.
As of C++11 <stddef.h>
(and its relatives) is deprecated, which means that the only means of acquiring size_t
in the global namespace without explicitly bringing it into the global namespace (e.g. via using std::size_t;
) is deprecated.
Deprecated library features could be removed in any future version of the standard library (and indeed some have been in the past), so it is bad practice to use deprecated features if you can avoid doing so.
Furthermore if you are using <cstddef>
(or its relatives) and expecting to get size_t
then your code is technically not standard C++ because it is relying on an implementation-specific detail.
To quote cppreference:
For some of the C standard library headers of the form
xxx.h
, the C++ standard library both includes an identically-named header and another header of the formcxxx
(all meaningfulcxxx
headers are listed above).With the exception of
complex.h
, eachxxx.h
header included in the C++ standard library places in the global namespace each name that the correspondingcxxx
header would have placed in thestd
namespace.These headers are allowed to also declare the same names in the
std
namespace, and the correspondingcxxx
headers are allowed to also declare the same names in the global namespace: including<cstdlib>
definitely providesstd::malloc
and may also provide::malloc
. Including<stdlib.h>
definitely provides::malloc
and may also providestd::malloc
. This applies even to functions and function overloads that are not part of C standard library.
3