Подтвердить что ты не робот

Лучше ли включать <cassert> или <assert.h>?

Используя С++ 11, лучше ли #include <cassert> или <assert.h>? Или нет разницы?

Edit:

Кажется, Должен ли я включать < xxxx.h > или <cxxxx> в программах на С++? утверждает, что это сводится к загрязнению глобального пространства имен. Является ли это особым случаем, потому что assert является макросом и нет std::assert?

4b9b3361

Ответ 1

Содержимое <cassert> совпадает с заголовком стандартной библиотеки C <assert.h>, за исключением того, что макрос с именем static_assert не определен. 1

Предпочитает <cassert>.

Все заголовки <xxx.h> C (включая <assert.h>) устарели:

D.5 C стандартные заголовки библиотек [des.c.headers]

Обновление макроса static_assert от C

В D.5 [des.c.headers], стандарт С++ относится к заголовкам <xxx.h> как "заголовки C:

1 Для совместимости со стандартной библиотекой C стандартная библиотека С++ предоставляет заголовки C, показанные в таблице 141.

В С++ 14 спецификация упоминается в C99 (ISO/IEC 9899: 1999). C99 не определил макрос static_assert (в любом заголовке). С++ 14 имел это сказать о <cassert> в 19.3 [утверждения]:

2 Содержимое совпадает с заголовком библиотеки стандартного C <assert.h>.

С++ 17 ссылок C11 (SO/IEC 9899: 2011), который определяет static_assert в <assert.h>, и это говорит о <cassert> в 22.3.1 [cassert.syn]:

1 Содержимое совпадает с заголовком стандартной библиотеки C <assert.h>, за исключением того, что макрос с именем static_assert не определен.

Оба С++ 14 и С++ 17 определяют <assert.h> только со ссылкой на их соответствующие спецификации C, а также следующим образом:

См. также: ISO C 7.2.

(это раздел C, который указывает <assert.h>)

Как я это читал, techincally <assert.h>, когда компилируется с помощью компилятора С++ 17, на самом деле определяет макрос с именем static_assert. Однако делать это было бы бессмысленно, и я не могу себе представить, что любая реализация на самом деле потрудилась сделать это.

В любом случае, я придерживаюсь своей рекомендации выше:

Предпочитает <cassert>.

Это просто способ С++. И, по крайней мере, в С++ 98/03/11/14/17, он избегает в зависимости от устаревших функций. Кто знает, что принесет С++ 20. Но С++ 20 определенно не будет осуждать <cassert>.


1 22.3.1 Сводка заголовка [cassert.syn]

2Ссылка на спецификацию С++ 11.

3Ссылка на спецификацию С++ 17.

Ответ 2

Глядя на код:

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

Оба они работают!


Какой из них лучше в С++ 11?

Относительно С++ 11 и С++ 17 спецификация:

C.5.1 (раздел из документа С++ 17)
Модификации заголовков [diff.mods.to.headers]

  • Для совместимости со стандартной библиотекой C стандартная библиотека С++ предоставляет заголовки C, перечисленные в D.5, но их использование устарел на С++.

  • Нет заголовков С++ для заголовков C, <stdnoreturn.h> и <threads.h>, а также заголовки C часть С++.

  • Заголовки С++ (D.4.1) и (D.4.4), а также их соответствующие заголовки C и, не содержат любое содержимое из стандартной библиотеки C и вместо этого просто включите другие заголовки из стандартной библиотеки С++.


Г .5 стандартные заголовки библиотеки [des.c.headers]1. Для совместимости со стандартной библиотекой C стандартная библиотека С++ предоставляет заголовки C, показанные в таблице 141.

введите описание изображения здесь

Оба документа С++ 11 и С++ 17 заявляют, что использование <X.h> остается совместимым со стандартом C, хотя их использование считается как устарел.


Что касается стандартного предложения С++ 20

Они анализируют "неопубликование" использование заголовков библиотеки C в С++ 20. <X.h> отображаются зеленым цветом. Отказ С++ 11 и С++ 17 на данный момент указан как "слабая рекомендация" и "настройка" для хранения " C стандартных заголовков библиотек (c.headers )":

"Основные заголовки библиотеки C - важная функция совместимости, и в ближайшее время они не собираются никуда". (из С++ 20 review документ)


Стандарт D.5 C
заголовки библиотек [des.c.headers]

Слабая рекомендация: В дополнение к вышесказанному, также удалите соответствующие C заголовки из стандарта С++, так как у нас нет соответствующие заголовки <stdatomic.h>, <stdnoreturn.h> или <threads.h>. Как и выше, но со следующими настройками: 20.5.5.2.1 C стандартные заголовки библиотек [c.headers]

Для совместимости со стандартной библиотекой C стандарт С++ библиотека предоставляет заголовки C, показанные в таблице 141. Таблица 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 и С++, уменьшают несовместимость столько, сколько возможное. Другие утверждают иначе, поскольку это усложняет ситуацию.

Итак, кажется, что <X.h> не никуда не годится. В конечном счете, вы можете использовать оба. Лично я бы принял решение о том, какой из них я бы использовал, чтобы ваш код был обратно совместим с кодом C или нет.