Лучше ли включать <cassert> или <assert.h>?
Используя С++ 11, лучше ли #include
<cassert>
или <assert.h>
? Или нет разницы?
Edit:
Кажется, Должен ли я включать < xxxx.h > или <cxxxx> в программах на С++? утверждает, что это сводится к загрязнению глобального пространства имен. Является ли это особым случаем, потому что assert
является макросом и нет std::assert
?
Ответы
Ответ 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 или нет.