【问题标题】:Where is size_t Defined?size_t 定义在哪里?
【发布时间】:2019-01-01 04:47:55
【问题描述】:

所以我知道C Compatability Headers 的任何标题:

将对应的 cxxx 标头放置在 std 命名空间中的每个名称放在全局命名空间中

我也知道这些 C 头文件自 起已被弃用,以支持它们的兼容性“cxxx”对应物。

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

多年来我一直在使用它,就像 size_t 一样,在我开始使用 std::size_t 之前,我想确认一下。

【问题讨论】:

  • Now, I believe that size_t is defined exclusively by the Standard Defines Header 并不完全正确,因为除了cstddef 之外的许多 C 兼容性库头文件都定义了它。
  • @François 我不确定这是不是重复的。 OP 想知道 ::size_t 是否已弃用。
  • @YSC 重复的地址,::size_t 不需要定义。我认为它解决了关于弃用的部分,因为标准不能弃用它没有定义的东西。

标签: c++17 c++ types namespaces size-t global-namespace


【解决方案1】:

我认为这在技术上意味着全局命名空间中 size_t 的定义已被弃用?

是的……但是。

标准只要求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);

[...]
头文件<cstddef>的内容和含义与C标准库头文件<stddef.h>相同,只是它没有声明类型wchar_­t,它还声明了类型byte及其相关操作(@ 987654336@),并在 [support.types.nullptr][support.types.layout] 中注明。

2)[extern.types]/1

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

3)[extern.types]/1

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

【讨论】:

    【解决方案2】:

    不推荐使用像 <stddef.h> 这样的 C 样式标题名称。但是,像 <cstddef> 这样的 C++ 风格的头文件可以在全局命名空间中声明它们的名称,然后通过 using-declarations (http://eel.is/c++draft/organization#headers-4) 在命名空间 std 中重新声明相同的名称。这种声明标准名称的方法未被弃用。许多实现正是这样做的,因此看到名称size_t 可以作为全局名称空间中的名称访问并不罕见。但这不能保证。因此,在包含 <cstddef> 的可移植 C++ 代码中,您应该使用 std::size_t 并且永远不要依赖 ::size_t 的可用性。

    【讨论】:

      【解决方案3】:

      标准说[expr.sizeof]

      sizeofsizeof... 的结果是std​::​size_­t 类型的常量。 [ 注意:std​::​size_­t 在标准头文件<cstddef> 中定义([cstddef.syn]、[support.types.layout])。 — 尾注 ]

      【讨论】:

      • 您在副本中有类似的答案。
      • @FrançoisAndrieux 这个答案不同,因为它没有添加到std::
      • Based on the above, I do not see why you cannot do: using size_t = decltype(sizeof 1); 你不能这样做(在全局命名空间中)。 ::size_t 是保留名称,因此定义它具有未定义的行为。
      • @user2079303 不再。
      • @YSC 从什么时候开始?保留here。草案是否与已发布的标准不同? For each type T ... the types ​::​T and ... are reserved to the implementation ... These types are ... size_­t ...
      【解决方案4】:

      size_t 定义在哪里?

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

      所以我认为这在技术上意味着全局命名空间中 size_t 的定义已被弃用?

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-03-22
        • 2016-02-19
        • 2016-12-31
        • 2011-10-08
        • 2010-09-30
        • 2013-04-04
        相关资源
        最近更新 更多