// 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);
[...]
The contents and meaning of the header<cstddef>
are the same as the C standard library header<stddef.h>
, except that it does not declare the typewchar_t
, that it also declares the typebyte
and its associated operations ([support.types.byteops]
), and as noted in[support.types.nullptr]
and[support.types.layout]
.
对于来自C标准库的每种类型
T
(这些类型是[...]size_t
,[...]。), 类型::T
和std::T
被保留给实现。
[...] 当定义时,
::T
应与std::T
相同。
类C的头文件名,如<stddef.h>
已经过时。然而,C++风格的头文件,如<cstddef>
允许在全局命名空间中声明其名称,然后通过使用声明(using-declarations)在std
命名空间中重新声明相同的名称 (http://eel.is/c++draft/organization#headers-4)。这种声明标准名称的方法并没有过时。许多实现正是这样做的,因此从全局命名空间访问名称size_t
并不罕见。但是这并不是保证的。因此,在包含<cstddef>
的可移植C++代码中,应该使用std::size_t
,永远不要依赖于::size_t
的可用性。
标准规定 [expr.sizeof]
:
sizeof
和sizeof...
的结果是类型为std::size_t
的常量。[注:在标准头文件<cstddef>
([cstddef.syn],[support.types.layout])中定义了std::size_t
。— 注解结束 ]
std::
。 - Maxim Egorushkinsize_t = decltype(sizeof 1);
。但是在全局命名空间中是不允许这样做的。::size_t
是一个保留名称,因此定义它会导致未定义的行为。 - eerorikasize_t的定义在哪里?
::size_t
在<stddef.h>
和其他一些C标准库头文件中被继承到C++中,它是保证被定义的。它可能会被实现定义,无论是否包含任何内容,因为它是保留的,但依赖于这种非保证的定义是不明智的。
所以我认为从技术上讲,全局命名空间中size_t的定义已经被弃用了吗?
确实如此。更准确地说,所有保证定义::size_t
的标准头文件现在在C++17中已被弃用。同样适用于所有其他非宏C库名称,例如::FILE
。
size_t
的定义不仅在标准定义头文件中(Standard Defines Header),因为除了cstddef
之外,许多C兼容库头文件都定义了它。 - eerorika::size_t
是否已被废弃。 - YSC::size_t
不需要被定义。我认为它解决了关于弃用部分的问题,因为标准不能弃用它没有定义的东西。 - François Andrieux