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

Должен ли я включать stddef.h или cstddef для size_t

Когда я хочу использовать size_t в С++, следует ли включать <stddef.h> или <cstddef>? Я слышал, как несколько человек говорили, что <cstddef> - плохая идея, и это должно быть устаревшим. Почему это?

4b9b3361

Ответ 1

Я предпочитаю #include <stddef.h>.

Некоторым именам в заголовках C разрешено быть макросами, но набор отличается от правил C. В C, EXIT_FAILURE, isdigit(), getc() a.o. являются макросами. Вы знаете, какие из них являются макросами на С++?

Во-вторых, для заголовка <cfoo> требуется только несколько стандартных заголовков C, заголовки Posix - нет. Знаете ли вы, какие заголовки являются стандартными и какие из них предоставляются только вашим компилятором?

В-третьих, при использовании заголовков из сторонней библиотеки C вы получите #include <stddef.h>, и я предпочитаю не смешивать <stddef.h> и <cstddef>.

В-четвертых, текущий черновик нового стандарта С++ говорит, что <cstdlib> разрешено выгружать символы в глобальное пространство имен (потому что, видимо, многие компиляторы уже делают это в наши дни), поэтому использование #include <cstdlib> не является гарантией того, что глобальное пространство имен будет незагрязнено в будущем. Поэтому я бы посоветовал, что при написании переносного кода вы должны предположить, что глобальное пространство имен будет затронуто (хотя оно теперь не разрешено). Как известно только некоторым экспертам (см. Обсуждение в комментариях здесь), лучше использовать <stddef.h>, поскольку даже начинающий программист на С++ поймет, что он загрязняет глобальное пространство имен.

Ответ 2

stddef.h является заголовком C. Имя size_t находится в глобальном пространстве имён. <cstddef>, с другой стороны, является заголовком С++, который переносит имена C в пространство имен std, что, естественно, является подходом С++, поэтому, если вы включите <cstddef>, а компилятор совместим, вам придется использовать std::size_t, Очевидно, что в С++ подход С++ более уместен. НТН

Изменить: Технически, заголовок C тоже может содержать имена в пространстве имен std. Но C-заголовки (те, которые заканчиваются на .h) вводят имена также в глобальное пространство имен (таким образом, загрязняя его) посредством использования-деклараций.

Ответ 3

<stddef.h> официально является устаревшей частью С++ (наряду с остальной частью приложения D стандарта С++). Все это (не устаревшие) части стандарта C, поэтому, несмотря на то, что они устарели на С++, они практически наверняка останутся доступными почти бесконечно.

Множество функций, которые не устарели, почти наверняка исчезнут сначала - export уже исчез из текущего черновика С++ 0x, и, если бы я должен был догадаться, я бы сказал, что спецификации исключений были гораздо вероятнее, чем Приложение D. Когда/если эти заголовки действительно станут устаревшими, вероятно, это будет из зрелой версии предложения модулей David Vandervoorde, которая может легко сделать все заголовки устаревшими.

В то же время большое количество компиляторов (особенно более старых) не реализует заголовки <c*> точно так, как это предусмотрено стандартом. Если вам нужно/нужно написать код, который работает с ними, вы получите совсем немного, используя заголовки <*.h> вместо заголовков <c*>.

В конечном счете, я думаю, что заголовки <c*> были решением проблемы поиска. В стандарте C требуется, чтобы эти заголовки определяли только имена, которые требуются - никаких других вообще, кроме имен, которые зарезервированы, например, с лидирующим подчеркиванием, за которым следует другое подчеркивание или заглавная буква. Зарезервированные имена (и еще несколько) также зарезервированы на С++, поэтому в любом случае они не могут столкнуться ни с чем в переносном коде. Таким образом, все заголовки <c*>, которые вы покупаете, - это возможность определить имя в глобальном пространстве имен, которое сталкивается с существующим именем в стандартной библиотеке C. Это такая впечатляюще ужасная идея, что ее даже не стоит рассматривать, так что с практической точки зрения вы ничего не получили.

Изменить: даже эта бесполезная возможность работала с несколькими достаточными реальными компиляторами, чтобы текущие черновики С++ 0x разрешали заголовкам <c*> загрязнять глобальное пространство имен, так что даже теоретическое преимущество ушло.

Ответ 4

Оба находятся в стандарте и AFAIK, чтобы остаться.

Форма cXXX всегда вводит имена в std пространства имен, форма XXX.h всегда вводит имена в глобальное пространство имен. Оба могут также помещать имена в другое пространство имен (по крайней мере, в С++ 0X, это было не так, как раньше). Поскольку соблюдение этого ограничения делает невозможным создание библиотеки С++ из библиотеки C, которую вы не контролируете, ограничение было удалено. g++ страдает этой проблемой хотя бы от целей без glibc).

Для традиционных заголовков Unix во всей реализации я протестировал форму XXX.h, включая дополнительный идентификатор Unix, если у вас есть необходимые макросы функций, определенные ранее. Поведение для формы cXXX противоречило между реализациями. Поэтому на практике я использую XXX.h, поскольку мне часто нужны эти объявления.

Ответ 5

<cstddef> является стандартным, а <stddef.h> - нет. В конце концов, это конец. Это не будет устаревшим в ближайшее время, потому что есть множество программ, которые зависят от него.