& Lt; cstdint & GT; vs & lt; stdint.h & gt;

В чем разница между 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?

73

Решение

Первоначальное намерение в 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 ++, но это не обязательно.

100

Другие решения

В том числе cstdint импортирует имена символов в пространстве имен std и возможно в глобальном пространстве имен.
В том числе stdint.h импортирует имена символов в глобальном пространстве имен и возможно в пространстве имен std.

Функции стандартной библиотеки C также представлены в стандартной библиотеке C ++, и в качестве общего соглашения об именах они предварительно добавляются с помощью c к соответствующим именам в стандартной библиотеке C.

В C ++ вы должны использовать:

#include <cstdint>

и полностью квалифицировать имена символов, которые вы используете с std::
в то время как в C, вы должны использовать:

#include <stdint.h>

Приложение D (нормативное) Особенности совместимости [depr] состояния:

Заголовки стандартной библиотеки D.6 C

1 Для совместимости со стандартной библиотекой C и C Unicode TR в стандартной библиотеке C ++ предусмотрены заголовки 25 C, как показано в таблице 151.

Который включает в себя:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h>
<complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h>
<ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h>
<errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h>
<fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

И далее,

2 Каждый заголовок C, каждый из которых имеет имя вида name.h, ведет себя так, как будто каждое имя помещено в стандартное пространство имен библиотеки cname header находится в глобальной области имен. Не указано, были ли эти имена сначала объявлены или определены в пределах области имен (3.3.6) пространства имен std, а затем введены в глобальную область имен с помощью явных объявлений using (7.3.3).

3 [Пример: заголовок <cstdlib> несомненно, предоставляет свои объявления и определения в пространстве имен std. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок <stdlib.h> несомненно, обеспечивает те же объявления и определения в глобальном пространстве имен, что и в стандарте C. Он также может предоставлять эти имена в пространстве имен std. — конец примера]

14

  1. cstdint заголовок C ++ 11, stdint.h такое заголовок C99 (C и C ++ — это разные языки!)

  2. MSVC 2008 не содержит ни stdint.h ни cstdint,

  3. Реализации cstdint в основном просто #include <stdint.h> с некоторыми исправлениями пространства имен / языка.

0