【问题标题】:Return value of std::strftimestd::strftime 的返回值
【发布时间】:2017-01-01 02:17:42
【问题描述】:

我想我在某处读到,如果我将 nullptr 传递给std::strftime,该函数将返回所需的缓冲区大小。事实上,以下代码在我尝试过的众多 Linux 系统上运行良好(但不是用 VS 编译时):

#include <iostream>
#include <ctime>
#include <string>

int main()
{
    std::time_t time{};
    std::tm const * ltime = std::localtime(&time);

    const char * formatString = "%Y-%b-%d";
    //allocate buffer of appropriate size
    auto requiredSize = 1 + std::strftime(nullptr, 50, formatString, ltime);
    std::cout << "Required buffer size:" << requiredSize << "\n";

    //Format time to string
    std::string buff(requiredSize, ' ');
    std::strftime(&buff[0], requiredSize, formatString, ltime);

    std::cout << buff << std::endl;
}

但是,我无法找到我的原始来源或任何其他说明此行为的文档。所以我的问题是:

  • 在哪些系统/编译器/标准库实现(如果有)上这是一种保证行为?
  • 在哪里可以找到相应的文档?

编辑:我添加了 C 标签,因为我已经看到与等效 C 代码相同的结果,并且至少使用 gcc/g++(或者更确切地说是 glibc/libstdc++)std::strftime 可能只是 c 函数的别名strftime 无论如何。

【问题讨论】:

  • IIRC 你声称的作品。我认为 cppreference 需要对此进行更新。
  • 文档:查看最新 C++ 标准的草案之一。它记录了库函数(但可能通过引用 C 标准)。请注意,有一条通用规则“您不能将 NULL 传递给库函数,除非它明确表示可以”。
  • 我认为创建堆栈缓冲区然后构造std::string直接传递堆栈缓冲区的地址和std::strftime()的返回值,将相同的堆栈缓冲区传递给它更有效其余格式参数。然后std::strftime填充堆栈缓冲区并返回正确的长度以直接构造std:string。这样可以省去两次调用st::strftime 和两次填写std::string 的麻烦。
  • @mikemb:它也不在 posix 中。它可能是一个未记录的 glibc 扩展。

标签: c++ c glibc


【解决方案1】:

据我所知以及其他人在 cmets 中所写,根据 ISO C 或 C++ 标准,上述代码很可能是未定义的行为,就我自己的实验而言,使用 VS2015 编译时会崩溃。

但是,就 glibc 而言,@rici 是正确的:

来自The GNU C Library的文档:

如果 s 是一个空指针,strftime 实际上不会写任何东西,而是返回它应该写的字符数。

【讨论】:

  • 如果您提到 C 或 C++ 标准或 POSIX 未指定此行为,则会改进此答案。对于 glibc 以外的实现,将空指针作为第一个参数传递给 strftime 具有未定义的行为。 (当然返回有用的信息与未定义的行为完全一致。)
  • 一个小问题:这是一个 glibc 问题;它与 gcc 或 g++ 没有直接关系。例如,您可以将 clang 或 clang++ 与 glibc 一起使用,并且您可以将 gcc 或 g++ 与其他库实现一起使用。
  • @KeithThompson:已修复。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2020-09-14
  • 2012-06-30
  • 2019-02-19
相关资源
最近更新 更多