【问题标题】:Does "std::size_t" make sense in C++?“std::size_t”在 C++ 中有意义吗?
【发布时间】:2008-10-26 01:55:05
【问题描述】:

在我继承的一些代码中,我看到size_t 经常与std 命名空间限定符一起使用。例如:

std::size_t n = sizeof( long );

当然,它编译并运行良好。但这对我来说似乎是一种不好的做法(可能是从 C 继承而来的?)。

size_t 不是内置在 C++ 中并因此位于全局命名空间中吗?在 C++ 中使用 size_t 是否需要包含头文件?

问这个问题的另一种方法是,以下程序(包含 no)是否应该在所有 C++ 编译器上编译

size_t foo()
{
    return sizeof( long );
}

【问题讨论】:

  • C 没有命名空间。
  • 它内置在 C++ 中,当你#include 时,它位于命名空间 std。请参阅下面的答案。
  • 这不是“提出这个问题的另一种方式”——这是一个不同的问题:main 返回 int。

标签: c++ size-t


【解决方案1】:

stackoverflow 人群似乎对此感到困惑

::size_t 在向后兼容标头 stddef.h 中定义。它从一开始就是ANSI/ISO CISO C++ 的一部分。每个 C++ 实现都必须附带 stddef.h(兼容性)和 cstddef,其中只有后者定义 std::size_t 而不一定是 ::size_t。请参阅 C++ 标准的附录 D。

【讨论】:

  • 这里绝对是最好的答案。它基于标准而不是特定的编译器。它回答了最初的问题而没有偏离正线。
  • 另一个不使用using namespace std的理由
  • @Darryl:公平地说,所有较旧的答案也是如此。
  • C++11 标准规定 cstddef 应该定义 stddef.h 所做的一切,包括 ::size_t。所以我认为没有理由使用 std::size_t 代替 size_t。请参阅“18.2.2: 内容与标准 C 库头文件 相同,有以下更改......”这里没有关于 ::size_t 的内容。
  • @eugene 答案是 c++03 特定的。随意扩展它以涵盖 C++11。一个优点是,如果这是目标之一,您的代码将保持符合 c++03。
【解决方案2】:

C++ 标准第 17.4.1.2 节第 4 段指出:

“但是,在 C++ 标准库中,声明和定义(在 C 中定义为宏的名称除外)在命名空间 std 的命名空间范围 (3.3.5) 内。”

这包括在模式 cname 的标题中找到的项目,包括定义 size_t 的 cstddef

所以 std::size_t 实际上是正确的。

【讨论】:

    【解决方案3】:

    您可以在全局命名空间中获得size_t,例如,包括<stddef.h> 而不是<cstddef>。我看不到任何明显的好处,并且该功能已被弃用。

    【讨论】:

    • 对否决票的一些解释是礼貌的。答案正确且符合主题。
    • 我不知道是谁投了你的票。您的观察与原始问题非常吻合。
    • 我对你投了反对票,主要是因为有一种不被弃用的方法:使用声明,即using std::size_t,你没有提到这是一个更好的选择。 :-)
    • 除了我认为@fizzer 是在解释你如何可能在你的 C++ 程序的全局命名空间中使用 size_t,而不是建议你 i> 所以。
    • 你没有真正回答这个问题。您回答了一个相关问题。
    【解决方案4】:

    size_t 没有内置在 C++ 中。并且默认情况下没有定义。这个不能用 GCC 编译:

    int main(int argc, char** argv) {
    size_t size;
    }
    

    也就是说,size_t 是 POSIX 的一部分,如果您只使用 <cstdlib> 之类的基本内容,您最终可能会定义它。

    您可以争辩说 std::size_t 是 size_t 的 C++ 等价物。正如布赖恩所指出的,std:: 被用作命名空间以避免设置不适合所有人的全局变量。它就像 std::string 一样,也可以在根命名空间中定义。

    【讨论】:

      【解决方案5】:
      std::size_t n = sizeof( long );
      

      实际上,您还没有问过上面的具体做法是什么。使用 size_t,使用 std 命名空间进行限定,...

      正如 C++ 标准 (18.1) 所说, size_t 是在标准 header 中定义的类型。我建议放弃关于可能从 C 语言继承的任何想法和印象。 C++ 是一种独立且不同的语言,最好这样考虑。它有自己的标准库,并且 C++ 标准库的所有元素都在命名空间 std 中定义。但是,可以在 C++ 程序中使用 C 标准库的元素。

      我会考虑将其作为一个肮脏的黑客。 C++ 标准规定标头的内容是相同的或基于 C 标准库中的相应标头,但在许多情况下,已应用了更改。换句话说,它不是将 C 头文件直接复制并粘贴到 C++ 头文件中。

      size_t 不是 C++ 中的内置类型。它是一种定义类型,用于指定使用哪种整数类型作为 sizeof() 运算符的返回类型,因为 sizeof() 的实际返回类型是实现定义的,所以 C++ 标准通过定义 size_t 来统一。

      下面的程序(没有 包括)预计编译 所有 C++ 编译器?

      size_t foo()
      {
          return sizeof( long );
      }
      

      C++ 标准说 (1.4):

      库中定义的名称具有命名空间范围 (7.3)。 C++ 翻译单元 (2.1) 通过包含适当的标准库头文件 (16.2) 来获得对这些名称的访问权。

      size_t 是在 std 命名空间中定义的名称,因此在这种情况下,每个使用此名称的程序都应包含相应的标头。

      接下来,3.7.3章节说:

      但是,除非通过包含适当的标头来声明名称,否则引用 std、std::bad_alloc 和 std::size_t 是不正确的。

      鉴于此,使用 size_t 但不包含标头的程序格式不正确。

      【讨论】:

        【解决方案6】:

        有时其他库会定义自己的 size_t。例如升压。 std::size_t 指定您肯定想要 c++ 标准。

        size_t 是一个 c++ 标准类型,它在命名空间 std 中定义。

        【讨论】:

        • 这是有道理的。你知道“::size_t”或“std::size_t”(或两者兼有)是语言规范的一部分吗?
        【解决方案7】:

        GNU 编译器头文件包含类似

        typedef long int __PTRDIFF_TYPE__;
        typedef unsigned long int __SIZE_TYPE__;

        然后 stddef.h 包含类似的东西

        typedef __PTRDIFF_TYPE__ ptrdiff_t;
        typedef __SIZE_TYPE__ size_t;

        最后,cstddef 文件包含类似

        #include 命名空间标准{ 使用 ::ptrdiff_t; 使用 ::size_t; }

        我认为这应该说清楚。只要您包含 ,您就可以使用 size_t 或 std::size_t 因为 size_t 在 std 命名空间之外进行了类型定义,然后被包含在内。实际上你有

        typedef long int ptrdiff_t;
        typedef unsigned long int size_t;
        
        命名空间标准{
        
          使用 ::ptrdiff_t;
          使用 ::size_t;
        
        }
        

        【讨论】:

        • 所以 GNU 是这样定义的,这是否意味着所有编译器都这样做?标准是否规定必须如此?
        【解决方案8】:

        我认为澄清已经足够清楚了。 std::size_t 在 C++ 中很有意义,::size_t 在 C 中(至少)很有意义。

        但是还有一个问题。即假设::size_tstd::size_t 兼容是否安全?

        从纯粹的类型安全的角度来看,它们不一定相同,除非在某处定义它们必须相同。

        我认为很多人都在使用一些东西:

        ----
        // a.hpp 
        #include <string>
        
        void Foo( const std::string & name, size_t value );
        
        -----
        // a.cpp
        #include "a.hpp"
        
        using namespace std;
        
        void Foo( const string & name, size_t value ) 
        {
          ...
        }
        

        因此,在标题中您肯定会使用::size_t,而在源文件中您将使用std::size_t。所以他们一定是兼容的,对吧?否则你会得到一个编译器错误。

        /迈克尔·S.

        【讨论】:

        • ::size_t 在没有命名空间的 C 中没有意义。
        猜你喜欢
        • 2018-10-18
        • 1970-01-01
        • 2012-09-11
        • 1970-01-01
        • 2011-09-12
        • 1970-01-01
        • 2014-10-17
        • 2014-08-21
        相关资源
        最近更新 更多