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:


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?

  • I never write std::size_t fwiw. Jul 14, 2014 at 23:07
  • Every C function has an equivalent alias in the std namespace, but I'm yet to see any project that does consistent use the std:: prefix for C-library calls.
    – glampert
    Jul 15, 2014 at 2:42

2 Answers 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).

  • 3
    <stddef.h> is a 100% standard header file in C++?? isn't anything with .h are c header?
    – Bryan Chen
    Jul 15, 2014 at 3:32
  • 3
    @Bryan: It assuredly is part of the C++ Standard. Section D.5 says "For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 26 C headers. Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope."
    – Ben Voigt
    Jul 15, 2014 at 5:43
  • 2
    @BenVoigt: Wouldn't that make cstddef the only 100% standard C++ header, and stddef.h something slightly less? Say 99.9%?
    – david.pfx
    Jul 15, 2014 at 8:45
  • 1
    @david.pfx: No it wouldn't. That is a normative rule, not a note, footnote, or suggestion. C++ places different requirements on the content of stddef.h than C does. And it is required for every hosted implementation.
    – Ben Voigt
    Jul 15, 2014 at 14:05
  • 1
    <stddef.h> is deprecated.
    – Pharap
    Dec 4, 2019 at 23:21

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 form cxxx (all meaningful cxxx headers are listed above).

With the exception of complex.h , each xxx.h header included in the C++ standard library places in the global namespace each name that the corresponding cxxx header would have placed in the std namespace.

These headers are allowed to also declare the same names in the std namespace, and the corresponding cxxx headers are allowed to also declare the same names in the global namespace: including <cstdlib> definitely provides std::malloc and may also provide ::malloc. Including <stdlib.h> definitely provides ::malloc and may also provide std::malloc. This applies even to functions and function overloads that are not part of C standard library.

  • You are saying they are deprecated solely because they are in Annex D, correct? It's possible that other parts of Annex D could be removed in a future version of the Standard, but this part NEVER will be... reading Annex D of the Standard as if only for "backward" compatibility is wrong, as all cross-compatibility and forward-compatibility concerns end up there. This particular one is necessary in new header files that can be included into both C and C++ context... which means the public header file of practically every library in the world.
    – Ben Voigt
    Dec 6, 2019 at 15:41
  • @BenVoigt Annexe D specifically defines deprecated as "Normative for the current edition of the Standard, but not guaranteed to be part of the Standard in future revisions"/"Normative for the current edition of this International Standard, but having been identified as a candidate for removal from future revisions" and includes the C standard library headers. You can make any argument as to why the standards committee will never remove it, but unless the committee has outright stated "we will never remove them" or later undeprecates them, any conjectural argument is irrelevant.
    – Pharap
    Dec 7, 2019 at 23:59
  • According the same reference, C++23 has undeprecated xxx.h headers. From cppreference: "xxx.h headers are deprecated in C++98 and undeprecated in C++23. These headers are discouraged for pure C++ code, but not subject to future removal."
    – jmou
    Mar 16, 2023 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.