Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to include <cassert> or <assert.h>? [duplicate]

Tags:

c++

c++11

Using C++11, is it better to #include <cassert> or <assert.h>? Or is there no difference?

Edit:

It seems Should I include <xxxx.h> or <cxxxx> in C++ programs? argues that it comes down to polluting the global namespace. Is this a special case because assert is a macro and there is no std::assert?

like image 385
TallBrianL Avatar asked Mar 25 '17 02:03

TallBrianL


People also ask

What is include assert H in C?

Advertisements. The assert. h header file of the C Standard Library provides a macro called assert which can be used to verify assumptions made by the program and print a diagnostic message if this assumption is false.

What is #include assert H in C++?

Answer: An assert in C++ is a predefined macro using which we can test certain assumptions that are set in the program. When the conditional expression in an assert statement is set to true, the program continues normally. But when the expression is false, an error message is issued and the program is terminated.

How do you assert in C++?

Assertions in C/C++ Following is the syntax for assertion. void assert( int expression ); If the expression evaluates to 0 (false), then the expression, sourcecode filename, and line number are sent to the standard error, and then abort() function is called.

What library is assert in?

h is a header file in the standard library of the C programming language that defines the C preprocessor macro assert() .


2 Answers

The contents of <cassert> are the same as the C standard library header <assert.h>, except that a macro named static_assert is not defined.1

Prefer <cassert>.

All of the <xxx.h> C headers (including <assert.h>) are deprecated:

D.5 C standard library headers [depr.c.headers]

Update regarding the static_assert macro from C

In D.5 [depr.c.headers], the C++ standard refers to the <xxx.h> headers as "the C headers:

1 For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 141.

In C++14, the specification referenced C99 (ISO/IEC 9899:1999). C99 did not define the macro static_assert (in any header). C++14 had this to say about <cassert> in 19.3 [assertions]:

2 The contents are the same as the Standard C library header <assert.h>.

C++17 references C11 (SO/IEC 9899:2011) which does define static_assert in <assert.h>, and has this to say about <cassert> in 22.3.1 [cassert.syn]:

1 The contents are the same as the C standard library header <assert.h>, except that a macro named static_assert is not defined.

Both C++14 and C++17 define <assert.h> only by reference to their respective C specifications, and also by this:

See also: ISO C 7.2.

(which is the C section that specifies <assert.h>)

The way I read this, techincally <assert.h>, when compiled with a C++17 compiler, actually does define a macro named static_assert. However doing so would be pointless, and I can't imagine that any implementation actually bothers to do so.

In any event, I stand by my recommendation above:

Prefer <cassert>.

It's just the C++ way to do things. And at least in C++98/03/11/14/17, it avoids depending on deprecated functionality. Who knows what C++20 will bring. But C++20 definitely will not deprecate <cassert>.


122.3.1 Header synopsis [cassert.syn]

2Link to the C++11 specification.

3Link to the C++17 specification.

like image 176
Howard Hinnant Avatar answered Sep 21 '22 03:09

Howard Hinnant


Looking at code:

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; } 

They both work!


Which one is better in C++11?

Regarding C++11's and C++17's specification:

C.5.1 (section from C++17 document)
Modifications to headers [diff.mods.to.headers]

  1. For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in D.5, but their use is deprecated in C++.

  2. There are no C++ headers for the C headers , <stdnoreturn.h>, and <threads.h>, nor are the C headers themselves part of C++.

  3. The C++ headers (D.4.1) and (D.4.4), as well as their corresponding C headers and , do not contain any of the content from the C standard library and instead merely include other headers from the C++ standard library.


D.5 C standard library headers [depr.c.headers] 1. For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 141.

enter image description here

Both C++11 and C++17 standard specifications documents state the use of <X.h> remains for compatibility with the C standard, although their use is regarded as deprecated.


Regarding the C++ 20 standard proposal

They are reviewing "undeprecating" the use of the C library headers in C++20. <X.h> appear highlighted in green. C++11 and C++17 deprecation, as of now, is stated as a "weak recommendation" and a "tweak" for keeping the "C standard library headers (c.headers)" is displayed below:

"The basic C library headers are an essential compatibility feature, and not going anywhere anytime soon." (from C++ 20 review document)


D.5 C standard
library headers [depr.c.headers]

Weak recommendation: In addition to the above, also remove the corresponding C headers from the C++ standard, much as we have no corresponding <stdatomic.h>, <stdnoreturn.h>, or <threads.h>, headers. As above, but with the following tweaks: 20.5.5.2.1 C standard library headers [c.headers]

For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 141. Table 141 — C headers

 <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> 

The header <complex.h> behaves as if it simply includes the header . The header <tgmath.h> behaves as if it simply includes the headers <complex> and <cmath>.


Bjarne Stroustrup recommends maximising inter-operability between the C and C++ languages, by reducing imcompatibilities as much as possible. Others argue otherwise, as it complicates things.

So, it seems <X.h> aren't going anywhere. Ultimately, you can use both. Personally, I would make the decision of which one I would use boil down to having your code backwards compatible with C code or not.

like image 40
Santiago Varela Avatar answered Sep 22 '22 03:09

Santiago Varela