size_t 在哪里定义的?

Where is size_t Defined?

所以我知道 C Compatability Headers 中的任何 header:

Places in the global namespace each name that the corresponding cxxx header would have placed in the std namespace

我还知道这些 C header 已从 开始弃用,以支持它们的兼容性 "cxxx" 对应项。

现在,我相信 size_t 完全由 Standard Defines Header 定义。所以我认为这在技术上意味着 size_t 在全局命名空间中的定义已被弃用?

多年来我一直在使用它,就像 size_t 一样,在我开始使用 std::size_t.

之前,我希望得到确认

I presume this technically means that the definition of size_t in the global namespace has been deprecated?

是的……但是。

标准只规定 std::size_t 必须由 <cstddef> 定义 1,它不禁止实现定义 ::size_t2,但如果实现的话,这两个定义必须匹配3.

总之,您应该使用 std::size_t 并且不应依赖 ::size_t 来定义或定义它。

以下为UB:

// DON'T
using size_t = std::size_t;        // UB
using size_t = decltype(sizeof 1); // UB

1) [cstddef.syn]

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 type wchar_­t, that it also declares the type byte and its associated operations ([support.types.byteops]), and as noted in [support.types.nullptr] and [support.types.layout].

2)[extern.types]/1

For each type T from the C standard library (These types are [...] size_­t,[...].), the types ​::​T and std​::​T are reserved to the implementation[.]

3)[extern.types]/1

[...] when defined, ​::​T shall be identical to std​::​T.

标准说[expr.sizeof]:

The result of sizeof and sizeof... is a constant of type std​::​size_­t. [ Note: std​::​size_­t is defined in the standard header <cstddef> ([cstddef.syn], [support.types.layout]). — end note ]

Where is size_t Defined?

::size_t 保证<stddef.h> 和 c++ 继承的其他一些 C 标准库头文件中定义。它 可能 由实现定义,无论是否包含任何内容,因为它是保留的,但依赖这种不确定的定义是不明智的。

So I presume this technically means that the definition of size_t in the global namespace has been deprecated?

确实如此。更准确地说,所有保证定义 ::size_t 的标准头文件现在在 C++17 中已弃用。这同样适用于所有其他非宏 C 库名称,例如 ::FILE.

C-style header 名称如 <stddef.h> 已弃用。然而,像 <cstddef> 这样的 C++ 风格的 header 允许在全局命名空间中声明它们的名称,然后在命名空间 stdusing-declarations 中重新声明相同的名称 (http://eel.is/c++draft/organization#headers-4)。这种声明标准名称的方法并未被弃用。许多实现正是这样做的,因此,将 name size_t 作为全局名称空间中的名称进行访问并不罕见。但这并不能保证。因此,在包含 <cstddef> 的可移植 C++ 代码中,您应该使用 std::size_t 而永远不要依赖 ::size_t 的可用性。