我应该为 size_t 包含 stddef.h 或 cstddef
当我想在 C++ 中使用 size_t
时,应该包含
还是
?我听到几个人说
是一个坏主意,应该被弃用。这是为什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
stddef.h
是 C 头文件。名称size_t
位于其中的全局命名空间中。另一方面,
是一个 C++ 标头,它将 C 名称包装到 std 命名空间中,这自然是 C++ 方法,因此如果包含std::size_t
。显然,在C++中,C++的方法更合适。从技术上讲,C 标头也可能包含 std 命名空间中的名称。但是 C 标头(以 .h 结尾的标头)也将名称引入了全局名称空间(从而污染了它)。
stddef.h
is the C header. The namesize_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 usestd::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).
我更喜欢
#include
。C 头文件中的某些名称允许是宏,但该集合与 C 规则不同。在 C 语言中,
EXIT_FAILURE
、isdigit()
、getc()
ao 都是宏。你知道C++中哪些是宏吗?其次,只需要几个标准 C 头文件就有
头文件,而 Posix 头文件则不需要。您知道哪些标头是标准的,哪些标头仅由您的编译器提供吗?第三,当使用第三方 C 库的头文件时,最终会得到< /code> 和
#include
,我不喜欢混合
。第四,新 C++ 标准的当前草案规定允许
将符号转储到全局命名空间中(因为显然现在许多编译器已经这样做了),因此使用# include
并不能保证全局命名空间将来不受污染。因此,我建议在编写可移植代码时,您应该假设全局名称空间将受到影响(即使现在不允许)。由于似乎只有少数专家知道这一点(请参阅此处评论中的讨论),因此最好使用
因为即使是 C++ 初学者也会明白它会污染全局命名空间。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.
已正式成为 C++ 的弃用部分(以及 C++ 标准附录 D 的其余部分)。所有这些都是标准 C 的(未弃用的)部分,因此即使它们在 C++ 中已弃用,它们实际上肯定会几乎无限期地保持可用。许多未弃用的功能几乎肯定会首先消失 -
export
已经从当前的 C++0x 草案中消失了,如果我不得不猜测的话,我想说异常规范比附件 D 更有可能被采用。当/如果这些标头确实变得过时时,它可能来自 David Vandervoorde 模块提案的成熟版本,它可以轻松呈现 所有标头均已过时。与此同时,相当多的编译器(尤其是较旧的编译器)并未完全按照标准规定的方式实现
标头。如果您想要/需要编写与它们一起使用的代码,那么通过使用<*.h>
标头而不是
可以获得相当多的好处> 标题。最终,我认为
标头是寻找问题的解决方案。 C 标准要求这些头文件仅定义所需的名称,除了保留的名称(例如前导下划线后跟另一个下划线或大写字母)之外,根本没有其他名称。保留名称(以及其他一些名称)也在 C++ 中保留,因此在任何情况下它们都不会与可移植代码中的任何内容发生冲突。因此,所有
标头为您提供了在全局命名空间中定义与 C 标准库中现有名称冲突的名称的能力。这是一个非常糟糕的想法,甚至不值得考虑去做,所以从实际的角度来看,你一无所获。编辑:即使这种无用的功能只适用于很少的真正编译器,当前的向上梳理 C++0x 草案也允许
标头污染全局命名空间,所以连理论上的优势都消失了。<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.两者都在标准中,并且,据我所知,将继续存在。
cXXX 形式始终引入 std 命名空间中的名称,XXX.h 形式始终引入全局命名空间中的名称。两者也可能将名称放在另一个命名空间中(至少在 C++0X 中,以前不是这种情况。由于遵守该约束,因此无法从您无法控制的 C 库构建 C++ 库,因此约束已被删除。g++ 至少在非 glibc 目标上遇到这个问题)。
对于传统的 Unix 标头,在所有实现中,如果您之前定义了所需的功能宏,我已经测试了 XXX.h 的形式,包括附加的 Unix 标识符。 cXXX 形式的行为在实现之间不一致。所以在实践中我使用 XXX.h 因为我经常需要这些声明。
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.
是标准,而
不是。事情到此就差不多结束了。它不会很快被弃用,因为有很多程序依赖于它。<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.