Так что я знаю любой заголовок из C Совместимость Заголовки:
Помещает в глобальное пространство имен каждое имя, которое соответствующий заголовок cxxx поместил бы в
std
Пространство имен
Я также знаю, что эти заголовки C устарели с C ++ 17, в пользу их совместимости с «cxxx» аналогами.
Теперь я считаю, что size_t
определяется исключительно Стандарт определяет заголовок. Так что я полагаю, что это технически означает, что определение size_t
в глобальном пространстве имен устарела?
Я использую его годами просто size_t
и я просто хотел бы получить подтверждение, прежде чем перейти к использованию std::size_t
,
Я полагаю, это технически означает, что определение size_t в глобальном пространстве имен устарело?
Стандарт только обязывает std::size_t
должен быть определен1 от <cstddef>
, это не запрещает реализацию для определения ::size_t
2, но если реализация делает, два определения должны совпадать3.
В заключение, вы должны использовать std::size_t
и не должен полагаться ни на ::size_t
быть определенным, ни определить это.
Следующие UB:
// DON'T
using size_t = std::size_t; // UB
using size_t = decltype(sizeof 1); // UB
[…] Содержание и значение заголовкаnamespace std { using ptrdiff_t = see below; using size_t = see below; using max_align_t = see below; using nullptr_t = decltype(nullptr);
<cstddef>
совпадают с заголовком стандартной библиотеки C<stddef.h>
за исключением того, что он не объявляет типwchar_t
, что он также объявляет типbyte
и связанные с ним операции ([support.types.byteops]
) и, как отмечено в[support.types.nullptr]
а также[support.types.layout]
,
Для каждого типа
T
из стандартной библиотеки C (Эти типы […]size_t
, […].), типы::T
а такжеstd::T
зарезервированы для реализации [.]
[…] когда определено,::T
должны быть идентичныstd::T
,
Названия заголовков в стиле C, такие как <stddef.h>
устарели. Тем не менее, C ++ — стиль заголовков, таких как <cstddef>
разрешено объявлять их имена в глобальном пространстве имен, а затем повторно объявлять те же имена в пространстве имен std
через с помощью деклараций (http://eel.is/c++draft/organization#headers-4). Такой подход к объявлению стандартных имен не считается устаревшим. И многие реализации делают именно это, поэтому нередко видеть имя size_t
доступно как имя из глобального пространства имен. Но это не гарантировано. Итак, в переносимом коде C ++, который включает в себя <cstddef>
ты должен использовать std::size_t
и никогда не полагаться на ::size_t
Доступность
Стандарт говорит [expr.sizeof]
:
Результат
sizeof
а такжеsizeof...
константа типаstd::size_t
, [ Заметка:std::size_t
определяется в стандартном заголовке<cstddef>
([cstddef.syn], [support.types.layout]). — конец примечания]
Где определен size_t?
::size_t
является гарантированный быть определенным в <stddef.h>
и несколько других заголовков стандартной библиотеки C, которые унаследованы c ++. Это может быть определенным реализацией независимо от того, включено ли что-либо или нет, поскольку оно зарезервировано, но полагаться на такое негарантированное определение было бы неразумно.
Итак, я предполагаю, что это технически означает, что определение size_t в глобальном пространстве имен устарело?
В самом деле. Точнее, все стандартные заголовки, которые гарантированно определяют ::size_t
теперь устарели в C ++ 17. То же самое относится ко всем другим не-макро-именам библиотек C, таким как ::FILE
,