我应该为size_t包含stddef.h或cstddef

fre*_*low 24 c++ namespaces naming-conventions size-t header-files

当我想size_t在C++中使用时,我应该包含<stddef.h>还是<cstddef>?我听过几个人说这<cstddef>是个坏主意,应该弃用.这是为什么?

Arm*_*yan 40

stddef.h是C头.该名称size_t位于全局命名空间中.<cstddef>另一方面,它是一个C++头,它将C名称包装到std命名空间中,这当然是C++方法,所以如果你包含<cstddef>并且编译器是兼容的,你将不得不使用std::size_t.显然,在C++中,C++方法更为合适.HTH

编辑:从技术上讲,C头也可能包含std命名空间中的名称.但是C-header(以.h结尾的那些)也通过using-declarations将名称引入全局命名空间(从而污染它).

  • 好决定.虽然`stddef.h`(以及其他17个C头文件)特别是C++ 03的一部分,但是它们会感染全局命名空间,你应该使用C++而不是兼容性函数--C++也提供了`malloc`但没有理智的C++程序员会使用它:-) (3认同)
  • @Sjoerd:§D.7/ 2说:"未指定这些名称是在名称空间`std`的名称空间作用域(3.3.6)中首先声明或定义的,然后通过显式*using注入全局名称空间作用域 - 声明*(7.3.3)." (2认同)
  • @Philipp:这是真的(不幸的是).对于当前的标准,可能更准确地看一下:http://www.open-std.org/jtc1/sc22/open/n2356/.这是1998年标准的最终草案,但03年的变化相对较小. (2认同)

Sjo*_*erd 13

我更喜欢#include <stddef.h>.

允许C头中的某些名称为宏,但该集与C规则不同.在C, ,,EXIT_FAILURE AO是宏.你知道哪些是C++中的宏?isdigit()getc()

其次,只有几个标准的C头需要有<cfoo>标题,而Posix标题则不需要.您知道哪些标题是标准的,哪些标题只是由编译器提供的?

第三,使用来自第三方的C库头时,您将结束#include <stddef.h>了,我不喜欢混<stddef.h><cstddef>.

第四,新C++标准的当前草案<cstdlib>允许将符号转储到全局命名空间中(因为现在很多编译器已经这样做了),因此使用#include <cstdlib>并不能保证全局命名空间将来不会被污染.所以我建议在编写可移植代码时,你应该假设全局命名空间会受到影响(即使现在不允许).由于只有少数专家似乎知道这一点(参见此处评论中的讨论),最好使用<stddef.h>即使是开始,C++程序员也会理解它会污染全局命名空间.

  • 这不是**最终会发生的事情,而是几乎所有编译器都已经做过的事情.这就是标准改变的原因,允许现有的做法!大多数C++编译器都必须使用系统C编译器的.h头文件,无论他们喜欢与否. (5认同)
  • 您列出的大多数原因听起来像是偏爱<cstddef>的参数. (4认同)
  • `<cstdlib>`是*not*"允许将符号转储到blobal名称空间.(§17.4.1.2/ 4):"然而,在C++标准库中,声明和定义(定义为的名称除外) C)中的宏位于命名空间std的命名空间范围(3.3.5)内." (2认同)

Jer*_*fin 11

<stddef.h>是C++的正式弃用部分(以及C++标准的附录D的其余部分).所有这些都是标准C的(非弃用)部分,因此即使它们在C++中被弃用,它们几乎肯定会无限期地保持可用状态.

许多未被弃用的功能几乎肯定会首先消失 - export已经从当前的C++ 0x草案中消失了,如果我不得不猜测,我会说异常规范的可能性要大于附件D.当/如果这些标题确实变得过时,它可能来自David Vandervoorde的模块提议的成熟版本,它可以轻松地使所有标题过时.

与此同时,相当数量的编译器(尤其是较旧的编译器)并没有<c*>完全按照标准规定的方式实现标头.如果您希望/需要编写适用于它们的代码,则可以通过使用<*.h>标头而不是<c*>标头来获得相当多的代码.

最终,我认为<c*>标题是寻找问题的解决方案.C标准要求这些标题定义所需的名称 - 除了保留的名称之外没有其他名称,例如使用前导下划线后跟另一个下划线或大写字母.保留的名称(以及更多)也在C++中保留,因此在任何情况下它们都不会与可移植代码中的任何内容冲突.因此,所有<c*>标题都可以在全局命名空间中定义与C标准库中的现有名称冲突的名称.这是一个非常糟糕的想法,它甚至不值得考虑做,所以从实际的角度来看,你什么也没有获得.

编辑:即使那些无用的功能与少数真正的编译器一起工作,上升的C++ 0x的当前草案<c*>仍然允许标题污染全局命名空间,所以即使理论上的优势也消失了.