В чем разница между stdint.h
и cstdint
?
Оба они доступны в MSVC (Visual Studio 2010) и gcc-4.5.1. Также оба определяют intX_t
/ uintX_t
типы (где X
размер в байтах типа).
- Если обоснование в обоих заголовках одинаково (переносимые типы), какие решения я должен принять, чтобы выбрать тот или другой?
В stdint.h
определяет каждый тип без какого-либо пространства имен, cstdint
типы лежат в std
пространстве имен.
- Есть ли причина включать или не включать определенные типы в
std
пространство имен? Чем отличаются эти два заголовка?
cstdint
не имеет расширения файла и использует c
префикс, stdint.h
использует .h
расширение.
- Каковы соглашения об именах для этих заголовков?
c
префикс указывает на то, что это библиотека C? есть причина отсутствия расширения файла вcstdint
?
<cstdint>
. Вот ошибка я получаю:./misc.h:7:10: fatal error: 'cstdint' file not found
.Ответы:
Первоначальное намерение C ++ 98 состояло в том, что вы должны использовать
<cstdint>
C ++, чтобы избежать загрязнения глобального пространства имен (ну, не<cstdint>
в частности, это добавлено только в C ++ 11, но<c*>
заголовки в целом).Однако реализации все равно продолжали помещать символы в глобальное пространство имен, и C ++ 11 одобрил эту практику [*]. Итак, у вас в основном есть три варианта:
<cstdint>
и либо полностью квалифицируйте каждый используемый вами целочисленный тип, либо добавьте его в область видимости с помощью иusing std::int32_t;
т. Д. (Раздражает, потому что многословен, но это правильный способ сделать это, как и для любого другого символа в стандартной библиотеке C ++)<stdint.h>
(немного плохо, потому что устарело)<cstdint>
и предполагайте, что ваша реализация поместит символы в глобальное пространство имен (очень плохо, потому что не гарантируется).На практике я подозреваю, что раздражающий большой объем кода использует последний вариант просто потому, что это легко сделать случайно в реализации, в которой
<cstdint>
символы помещаются в глобальное пространство имен. Вы должны попробовать использовать первое. У второго есть одно достоинство: он гарантированно помещает что-то в глобальное пространство имен, а не только, возможно, делает это. Я не думаю, что это особенно полезно, но это может сэкономить немного времени на вводе текста, если это ваш приоритет.Есть четвертый вариант,
#include <cstdint>
заusing namespace std;
которым иногда бывает полезно, но есть места, куда не следует помещатьusing namespace std;
. У разных людей разные представления о том, где находятся эти места, но «на верхнем уровне в файле заголовка» хуже, чем «на верхнем уровне в файле cpp», что хуже, чем «в ограниченном объеме». Некоторые людиusing namespace std;
вообще никогда не пишут .[*] Это означает, что стандартные заголовки C ++ могут помещать данные в глобальное пространство имен, но не обязательны. Таким образом, вы должны избегать столкновения с этими символами, но вы не можете их использовать, потому что их может не быть. По сути, глобальное пространство имен в C ++ - это минное поле, старайтесь его избегать. Кто-то может возразить, что комитет ратифицировал практику реализации, которая почти так же вредна, как закрепление
using namespace std;
на верхнем уровне в файле заголовка - разница в том, что реализации делают это только для символов в стандартной библиотеке C, тогдаusing namespace std;
как для C ++. -только символы. В стандарте C есть раздел, в котором перечислены имена, зарезервированные для будущих дополнений к стандарту. Считать эти имена зарезервированными и в глобальном пространстве имен C ++ - не совсем глупая идея, но это не обязательно.источник
<iostream>
,<vector>
,<cstdlib>
, кроме тех , которые включены для обеспечения совместимости C:<stdint.h>
,<stdlib.h>
. И да, начальная букваc
указывает на то, что она<cstdlib>
является эквивалентом C ++ стандартного заголовка C<stdlib.h>
, а не является полностью новым для C ++, как<vector>
есть. Есть заголовок C ++<complex>
, поэтому нам остается только надеяться, что ни в одной будущей версии C не будет стандартного заголовка<omplex.h>
.<omplex.h>
, что нет<complex.h>
. Если добавить<omplex.h>
C, эквивалент C ++ будет<complex>
.Включение
cstdint
импортирует имена символов в пространство имен std и, возможно, в глобальное пространство имен.Включение
stdint.h
импортирует имена символов в глобальное пространство имен и, возможно, в пространство имен std.Возможности стандартной библиотеки C также предоставляются в стандартной библиотеке C ++, и в качестве общего соглашения об именах они добавляются к соответствующим именам в стандартной библиотеке C.
В C ++ вы должны использовать:
#include <cstdint>
и полностью уточните имена символов, которые вы используете
std::
в C, вы должны использовать:
#include <stdint.h>
В приложении D (нормативное) Характеристики совместимости [depr] говорится:
D.6 Заголовки стандартной библиотеки C
Который включает в себя:
И далее,
источник
cstdint
это заголовок C ++ 11, заголовокstdint.h
C99 (C и C ++ - разные языки!)MSVC 2008 не содержит ни,
stdint.h
ниcstdint
.Реализации в
cstdint
основном просто#include <stdint.h>
с некоторыми исправлениями пространства имен / языка.источник
cstdint
необходимо поднять реализации в пространство именstd
.stdint.h
. Нет аргумента, чтоcstdint
это заголовок C ++.stdint.h
она не является частью C ++ 11. Фактически этого требует C ++ 11. Вы могли бы сказать: «int
находится на C ++ 11;long
находится на C99; C и C ++ - разные языки!», И это тоже не будет ложным. Однако мой пример еще более вводит в заблуждение, поскольку C ++ 11 частично ссылается на C99 для определения содержимого обоихstdint.h
иcstdint
, но не ссылается на C для определенияint
.