When I want to use size_t
in C++, should I include <stddef.h>
or <cstddef>
? I have heard several people saying that <cstddef>
was a bad idea, and it should be deprecated. Why is that?

- 46,613
- 43
- 151
- 237

- 256,549
- 94
- 388
- 662
-
1Check out my updated answer here. http://stackoverflow.com/questions/13889467/should-i-include-xxxx-h-or-cxxxx-in-c-programs/43016708#43016708 – Santiago Varela Mar 25 '17 at 15:38
5 Answers
stddef.h
is the C header. The name size_t
is in global namespace in it. <cstddef>
, on the other hand, is a C++ header which wraps the C names into std namespace, which is naturally the C++ approach, so if you include <cstddef>
and the compiler is compliant you'll have to use std::size_t
. Clearly, in C++, C++ approach is more appropriate.
Technically, the C header too may contain the names in the std namespace. But the C-headers (those that end with .h) introduce the names also to the global namespace (thus polluting it).

- 10,591
- 9
- 64
- 104

- 130,161
- 59
- 324
- 434
-
4Good call. While `stddef.h` (and 17 other C headers) are _specifically part of C++03, they infect the global namespace and you should be, as you say, using C++ rather than the compatibility functions - C++ also provides `malloc` but no sane C++ programmer would use it :-) – paxdiablo Feb 22 '11 at 14:36
-
1
-
3@Sjoerd: §D.7/2 says: “It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace `std` and are then injected into the global namespace scope by explicit *using-declarations* (7.3.3).” – Philipp Feb 22 '11 at 14:46
-
Sorry, Armen, I'd already added that bit to the first paragraph :-) Hope you don't mind. – paxdiablo Feb 22 '11 at 14:46
-
Also see the example in §D.7/3: “It [the header `
`] **may** also provide these names within the namespace `std`.” (emphasis added) – Philipp Feb 22 '11 at 14:48 -
-
@Armen: No, `stddef.h` doesn’t need to provide `std::size_t` (and in fact, it doesn’t provide it when compiling with G++ 4.4.3). – Philipp Feb 22 '11 at 14:52
-
1The _current_ standard states in D5/2: "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 also placed within the namespace scope of the namespace std and is followed by an explicit using-declaration". This may be changing in C++0x (I don't know) but I think this answer is correct based on that. – paxdiablo Feb 22 '11 at 14:56
-
1@pax: That would mean that G++ breaks the current standard, right? Maybe that was the reason why it was changed. – Philipp Feb 22 '11 at 15:01
-
gcc has things like `-std=c99` so I doubt that g++ _breaks_ the standard, it's just you may have to select the right flags. – paxdiablo Feb 22 '11 at 15:04
-
@pax: I've tested it with `-pedantic` and with both `-std=c++98` and `-std=c++0x` (there is no C++03 in G++ 4.4.3), with the same result. `#include
` simply seems to include the C file `stddef.h` that has no provisions for C++. – Philipp Feb 22 '11 at 15:11 -
1@Philipp Correct, gcc was/is non-compliant on this point. I've won several bets with C++ programmers on this point as they rely too much on gcc being always correct :). – Sjoerd Feb 22 '11 at 15:12
-
See this link for some quotes and additional links: http://stackoverflow.com/questions/2587445/are-c-functions-declared-in-c-headers-guaranteed-to-be-in-the-global-namesp/2588103#2588103 – Sjoerd Feb 22 '11 at 15:16
-
@Sjoerd: The problem is that the C++ standard isn't publicly available, so one often has to trust the compiler. Indeed I'm quite surprised about such a bug. Is there no bug report yet? – Philipp Feb 22 '11 at 15:21
-
@philipp Almost every line of the C++ standard has been quoted in some C++ discussion, so google can be useful. Even the Wikipedia article mentions this point: http://en.wikipedia.org/wiki/C%2B%2B_Standard_Library#C_Standard_Library – Sjoerd Feb 22 '11 at 15:26
-
More links: Dietmar Kuehl in 2006: http://bytes.com/topic/c/answers/457093-help-where-size_t#post1756650. – Sjoerd Feb 22 '11 at 15:30
-
@Armen Technically, the C++ header **may** contain the names in the global namespace, so pollution can never be ruled out. – Sjoerd Feb 22 '11 at 15:41
-
1@Philipp: the C++ standard certainly *is* publicly available (though not free). Drafts of the standard are also available, and *are* free (and the final draft rarely differs from the real standard enough for most people to notice or care). – Jerry Coffin Feb 22 '11 at 16:21
-
@Jerry: The latest draft for C++03 isn't freely available either, so I'm always quoting from the latest C++0x draft, where the behavior was changed. – Philipp Feb 22 '11 at 17:33
-
@Sjoerd: Thanks for the links, but unfortunately the Wikipedia page says "should" instead of "shall." – Philipp Feb 22 '11 at 17:37
-
2@Philipp: That's true (unfortunately). For the current standard, it's probably more accurate to look at: http://www.open-std.org/jtc1/sc22/open/n2356/. That's the final draft of the 1998 standard, but the changes in '03 were relatively minor. – Jerry Coffin Feb 22 '11 at 17:40
I prefer #include <stddef.h>
.
Some of the names in the C headers are allowed to be macros, but the set differs from the C rules. In C, EXIT_FAILURE
, isdigit()
, getc()
a.o. are macros. Do you know which ones are macros in C++?
Secondly, only a couple standard C headers are required to have the <cfoo>
header, Posix headers are not. Do you know which headers are standard and which ones are provided by your compiler only?
Thirdly, when using headers from a third-party C library, you will end up with #include <stddef.h>
, and I prefer not to mix <stddef.h>
and <cstddef>
.
Fourthly, the current draft for the new C++ standard says that <cstdlib>
is allowed to dump the symbols into the global namespace (because apparently many compilers already do so nowadays), so using #include <cstdlib>
is not a guarantee that the global namespace will be unpolluted in the future. So I would advice that when writing portable code, you should assume the global namespace will be affected (even though it is not allowed now). As only a few experts seem to know this (see the discussion in the comments here), it is better to use <stddef.h>
as even a beginning C++ programmer will understand that it pollutes the global namespace.

- 6,837
- 31
- 44
-
5`
` is *not* "allowed to dump the symbols into the blobal namespace. (§17.4.1.2/4): "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." – Jerry Coffin Feb 22 '11 at 16:15 -
@Jerry See the latest version of the (future) C++0x at http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 Quote: "[Example: The header
assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. [..]" – Sjoerd Feb 22 '11 at 16:29 -
1@Sjoerd: yes, that may (probably will) eventually happen -- but it's not currently allowed. – Jerry Coffin Feb 22 '11 at 16:37
-
5It is not something that will **eventually** happen, it is what almost all compilers already do. That's why the standard was changed, to allow existing practice! Most C++ compilers will have to use the .h headers from the system C compiler, whether they like it or not. – Bo Persson Feb 22 '11 at 17:37
-
@Bo Editted the text once more. Maybe I should refactor my text after all the bug-fixes?! :P – Sjoerd Feb 22 '11 at 18:18
-
6Most of the reasons you list sound like arguments for preferring
. – Adrian McCarthy Nov 09 '12 at 21:08
<stddef.h>
is officially a deprecated part of C++ (along with the rest of Annex D of the C++ standard). All of these are (non-deprecated) parts of Standard C, so even though they're deprecated in C++, they're virtually certain to remain available almost indefinitely.
A lot of features that aren't deprecated will almost certain disappear first -- export
is already gone from the current draft of C++0x, and if I had to guess, I'd say exception specifications were a lot more likely to go than Annex D. When/if these headers do become truly obsolete, it'll probably be from a mature version of David Vandervoorde's modules proposal, which could easily render all headers obsolete.
At the same time, a fair number of compilers (especially older ones) don't implement the <c*>
headers exactly the way the standard prescribes. If you want/need to write code that works with them, you gain quite a bit by using the <*.h>
headers instead of the <c*>
headers.
Ultimately, I think the <c*>
headers were a solution in search of a problem. The C standard requires that these headers only define the names that are required -- no others at all except names that are reserved, such as with a leading underscore followed by another underscore or a capital letter. The reserved names (and a few more) are reserved in C++ as well, so they can't collide with anything in portable code in any case. As such, all the <c*>
headers buy you is the ability to define a name in the global namespace that collides with an existing name in the C standard library. That is such a spectacularly awful idea that it's not even worth considering doing, so from a practical viewpoint you've gained nothing.
Edit: Even that useless capability worked with few enough real compilers that the current drafts of the up-combing C++0x give permission for the <c*>
headers to pollute the global namespace anyway, so even the theoretical advantage is gone.

- 476,176
- 80
- 629
- 1,111
-
It's even worse than you descibe: The `
` headers are allowed to put the names into the global namespace, thus the ` – Sjoerd Feb 22 '11 at 16:16` headers don't even buy you the ability to define a name in the global namespace that collides with an existing name in the C standard library. -
@Sjoerd: See my comment to your (incorrect) reply saying the same. It's true that many implementations *do* that, but it's *not* allowed by the current standard. – Jerry Coffin Feb 22 '11 at 16:18
-
The proposed wording of C++0x allows it, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 . – Sjoerd Feb 22 '11 at 16:30
Both are in the standard and, AFAIK, there to stay.
The form cXXX always introduces the names in the std namespaces, the form XXX.h always introduces the names in the global namespace. Both may also put the names in the other namespace (at least in C++0X, it wasn't the case previously. As respecting that constraint make it impossible to build a C++ library from a C library you don't control, the constraint was removed. g++ suffers of that problem at least on the non glibc targets).
For traditional Unix headers, in all implementation I've tested the form XXX.h includes the additional Unix identifier if you have the needed feature macros defined before. The behavior for the form cXXX was inconsistent between implementations. So in practice I use the XXX.h as I often need those declarations.

- 51,233
- 8
- 91
- 143
-
+1 for mentioning the inconsistency of
implementations, which historically was for me the most compelling reason. – Sjoerd Feb 22 '11 at 14:53 -
I severely doubt that `stddef.h` will ever be banned, but technically, it's permitted because the standard says: "These are […] not guaranteed to be part of the Standard in future revisions". – Philipp Feb 22 '11 at 14:56
-
2@Philipp, there are things which were not mentioned in such a clause which were removed, and things which are which is staying along... – AProgrammer Feb 22 '11 at 15:02
-
@Philipp: Which is exactly the definition of the term "deprecated" :) – Armen Tsirunyan Feb 22 '11 at 15:06
-
@Armen: Exactly what I've quoted, see §D/2: "… where *deprecated* is defined as: Normative for the current edition of the Standard, but not guaranteed to be part of the Standard in future revisions." – Philipp Feb 22 '11 at 15:13
-
@Philipp: the problem is that this is no different from any other part of the standard -- nothing is guaranteed to be in a future version of the standard, even if it's *not* deprecated (e.g., `export`). – Jerry Coffin Feb 22 '11 at 16:19
-
@Jerry: I agree, the usage of "deprecated" is quite vague. I think `export` could have been removed because most major compilers didn't implement it. "Deprecated" seems to be more of a wish than a definition. On the other hand, I'm not convinced that including the C header is actually preferable—at least it's inconsistent. – Philipp Feb 22 '11 at 17:42
<cstddef>
is Standard, and <stddef.h>
is not. That's pretty much the end of that. It's not going to be deprecated any time soon because there's a bunch of programs that depend on it.

- 144,682
- 38
- 256
- 465
-
4
-
@VJo: I have no idea, and don't quote paragraph about anything that's Standard. But I know that it is. Someone else is the Standard bible. I'll ask them. – Puppy Feb 22 '11 at 14:27
-
3`stddef.h` is _explicitly_ mentioned in C++03, the current standard. See Armen's answer for the reason why you shouldn't use them but they're definitely part of ISO C++. – paxdiablo Feb 22 '11 at 14:37
-
1§D.7/1: “For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 *C headers*, […]”; that means `
` is part of the C++ standard, but deprecated. – Philipp Feb 22 '11 at 14:41