包含<cassert>或<assert.h>更好吗?

时间:2017-03-25 02:07:33

标签: c++ c++11

使用C ++ 11,#include <cassert><assert.h>会更好吗?或者没有区别?

编辑:

似乎Should I include <xxxx.h> or <cxxxx> in C++ programs?认为它归结为污染全局命名空间。这是一种特殊情况,因为assert是一个宏而且没有std::assert吗?

2 个答案:

答案 0 :(得分:32)

<cassert>的内容与C标准库标题<assert.h>相同,只是未定义名为static_assert的宏。 1

首选<cassert>

不推荐使用所有<xxx.h> C标头(包括<assert.h>):

D.5 C标准库头文件[depr.c.headers]

有关C

static_assert宏的更新

在D.5 [depr.c.headers]中,C ++标准将<xxx.h>标题称为“ C标题

  

1为了与C标准库兼容,C ++标准库提供了表141中所示的 C头

在C ++ 14中,该规范引用了C99(ISO / IEC 9899:1999)。 C99没有定义宏static_assert(在任何标题中)。 C ++ 14在19.3 [断言]中对<cassert>说了这个:

  

2内容与标准C库标题<assert.h>相同。

C ++ 17引用了C11(SO / IEC 9899:2011),其中 定义了static_assert中的<assert.h>,并对<cassert>进行了说明在22.3.1 [cassert.syn]中:

  

1除了未定义名为<assert.h>的宏之外,内容与C标准库标题static_assert相同。

C ++ 14和C ++ 17仅通过引用它们各自的C规范来定义<assert.h>,并且也是这样:

  

参见:ISO C 7.2。

(这是指定<assert.h>的C部分)

我读这个的方式, techincally <assert.h>,当用C ++ 17编译器编译时,实际上 定义一个名为{{1}的宏}。然而,这样做是没有意义的,我无法想象任何实现实际上都不愿意这样做。

无论如何,我坚持上面的建议:

  

首选static_assert

这只是C ++的做事方式。至少在C ++ 98/03/11/14/17中,它避免了依赖于已弃用的功能。谁知道C ++ 20会带来什么。但是C ++ 20肯定不会弃用<cassert>

1 22.3.1标题提要[cassert.syn]

2 Link to the C++11 specification.

3 Link to the C++17 specification.

答案 1 :(得分:6)

查看代码:

Using assert.h   // Compatible with C language standard
---------------
#include <assert.h>

int main() {
    assert(true == true); // Execution continues
    assert(true == false); // Execution will abort with false value assert!
    return 0;
}

Using cassert    // Not compatible with C language standard
--------------
#include <cassert>

int main() {
    assert(true == true); // Execution continues
    assert(true == false); // Execution will abort with false value assert!
    return 0;
}

他们都有效!

哪一个在C ++ 11中更好?

关于C++11C++17的规范:

  

C.5.1 (C ++ 17文件部分)
  对标题的修改[diff.mods.to.headers]

     
      
  1. 为了与C标准库兼容,C ++标准库提供了D.5中枚举的C头,但它们的用途是   在C ++中弃用。

  2.   
  3. C标头<stdnoreturn.h><threads.h>没有C ++标头,C标头本身也没有   C ++的一部分。

  4.   
  5. C ++标题(D.4.1)和(D.4.4),以及它们对应的C标题和,不   包含来自C标准库的任何内容,而不是   仅包含C ++标准库中的其他标题。

  6.   
  

<强> D.5    C标准库头文件[depr.c.headers]   1.为了与C标准库兼容,C ++标准库提供了表141中所示的C头。

enter image description here

C ++ 11 C ++ 17 标准规范文档都声明<X.h>的使用仍然与C标准兼容,尽管它们的使用被视为已弃用

关于C++ 20 standard proposal

他们正在审核“不引用”在C ++ 20中使用C库头文件。 <X.h>以绿色突出显示。 C ++ 11和C ++ 17弃用,截至目前,被称为“弱推荐”和“调整”用于保留“ C标准库头文件(c.headers) )“显示如下:

  

“基本的C库标题是必不可少的兼容性功能,不会很快到达任何地方。”(来自C++ 20 review document

  

D.5 C标准
  库标题[depr.c.headers]

     

弱推荐:除上述内容外,还要删除   与C ++标准相对应的C头,就像我们没有的那样   相应的<stdatomic.h><stdnoreturn.h><threads.h>标题。   如上所述,但有以下调整:   20.5.5.2.1 C标准库头[c.headers]

     

与C标准库兼容,即C ++标准   library提供表141中所示的C头。表141-C   头

 <assert.h>  <inttypes.h>   <signal.h>      <stdio.h>   <wchar.h>
 <complex.h> <iso646.h>     <stdalign.h>    <stdlib.h>  <wctype.h>
 <ctype.h>   <limits.h>     <stdarg.h>      <string.h>  
 <errno.h>   <locale.h>     <stdbool.h>     <tgmath.h>
 <fenv.h>    <math.h>       <stddef.h>      <time.h>
 <float.h>   <setjmp.h>     <stdint.h>      <uchar.h>
  

标题<complex.h>   表现得好像只包含标题。   标题<tgmath.h>的行为就像它只包含标题<complex><cmath>

  

Bjarne Stroustrup 建议最大化互操作性    C和C ++语言减少不兼容性   可能。其他人则反驳说,因为它使事情复杂化。

所以,似乎<X.h> 不会去任何地方。最终,你可以使用两者。就个人而言,我会决定使用哪一个将您的代码向后兼容C代码