size_t被定义在哪里?

8

我知道任何来自C兼容性头文件的头文件:

在全局命名空间中放置相应cxxx头文件会放置在std命名空间中的每个名称

我也知道这些C头文件已经被弃用,作为它们的兼容"cxxx"对应项,从开始。

现在,我相信size_t是由标准定义头文件专门定义的。因此,我认为这在技术上意味着全局命名空间中size_t的定义已经被弃用了?

我已经使用它多年,只是作为size_t,在我转向使用std::size_t之前,我想确认一下。


现在,我相信size_t的定义不仅在标准定义头文件中(Standard Defines Header),因为除了cstddef之外,许多C兼容库头文件都定义了它。 - eerorika
3
我不确定这是否是重复问题。提问者想知道::size_t是否已被废弃。 - YSC
@YSC 这个重复的帖子确实提到了 ::size_t 不需要被定义。我认为它解决了关于弃用部分的问题,因为标准不能弃用它没有定义的东西。 - François Andrieux
4个回答

6
我认为这在技术上意味着全局命名空间中的size_t定义已被弃用?
是的,但是...
标准只要求std::size_t必须由定义,它不会禁止实现定义::size_t,但如果实现定义了,两个定义必须匹配。
总之,你应该使用std::size_t,既不依赖于::size_t的定义,也没有定义它。
以下内容是未定义行为:
// 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

对于来自C标准库的每种类型T(这些类型是[...] size_­t,[...]。), 类型::​Tstd​::​T被保留给实现。

3)[extern.types]/1

[...] 当定义时,::​T应与std​::​T相同。


3

类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的可用性。


1

标准规定 [expr.sizeof]:

sizeofsizeof... 的结果是类型为 std::size_t 的常量。[注:在标准头文件 <cstddef>([cstddef.syn],[support.types.layout])中定义了 std::size_t。— 注解结束 ]


你在重复问题中有一个类似的答案。 - François Andrieux
@FrançoisAndrieux 这个答案不同,因为它没有添加到 std:: - Maxim Egorushkin
基于上述内容,我不明白为什么你不能这样做:使用 size_t = decltype(sizeof 1);。但是在全局命名空间中是不允许这样做的。::size_t 是一个保留名称,因此定义它会导致未定义的行为。 - eerorika
@user2079303 不再了。 - YSC
@YSC 从什么时候开始?它在这里被保留(http://eel.is/c++draft/reserved.names#footnote-182)。草案与已发布的标准有何不同?“对于每种类型T......类型::T和......对于实现是保留的......这些类型是......size_​​t...” - eerorika
@user2079303 撤回了那个说法,似乎并不太受欢迎。 - Maxim Egorushkin

0

size_t的定义在哪里?

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

所以我认为从技术上讲,全局命名空间中size_t的定义已经被弃用了吗?

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接