在cout上打印我们的时间时出现了奇怪的C++行为

Weird C++ Behavior while printing our time on cout

本文关键字:行为 C++ cout 打印 我们 时间      更新时间:2023-10-16

运行以下代码:

  1 #include <iostream>
  2 int main(int argc, char** argv)
  3 {
  4     time_t t1 = time(0);
  5     time_t t(0);
  6     std::cout<<"BUG LINE"<<std::endl<< ctime(&t) << ctime(&t1) ;
  7     std::cout<<"PRINTS FINE HERE"<<std::endl;
  8     std::cout<< ctime(&t);
  9     std::cout<< ctime(&t1);
 10     return 0;
 11 }

建筑:g++test1.cpp

Output:
./a.out
BUG LINE
Thu Jan  1 01:00:00 1970
Thu Jan  1 01:00:00 1970
PRINTS FINE HERE
Thu Jan  1 01:00:00 1970
Wed Jul 10 16:31:48 2013

为什么代码的#6中的流会变得奇怪??

http://www.cplusplus.com/reference/ctime/ctime/

返回的值指向一个内部数组,其有效性或值可能会被任何后续对asctimectime的调用所更改。

http://en.cppreference.com/w/cpp/chrono/c/ctime

该字符串可以在std::asctimestd::ctime之间共享,并且可以在每次调用这些函数中的任何函数时被覆盖

在您的示例中,在第6行,首先计算ctime(&t1),然后覆盖字符串的ctime(&t)(先计算的是未指定的,编译器通常按相反的顺序计算(通常,而不是总是))。

TL;DR:阅读文档可能会有所帮助。

函数ctime返回一个static字符串缓冲区-因此每次返回的字符串都是完全相同的字符串),这意味着在同一行多次调用它将产生未定义的行为(因为C和C++标准不知道调用的顺序)。

解决方案是调用两个不同的语句(中间有;),或者使用可重入安全变量,在其中传递缓冲区以将结果存储在),例如ctime_r

这里的问题是ctime()使用了一个内部分配的char数组,每次调用ctime()都会对其进行修改。

这里的另一个问题是,您的ctime()可以在该表达式中以任何顺序进行求值。所以这里发生的是,第6行的这两个值都被求值了,但很明显,第二个值是第二个。然后从左到右应用运算符,但对ctime的两个调用都已经进行了评估,最左边的一个调用是在之后进行的,现在两个字符串都引用了相同的内容。

如果你把它们放在不同的线上,你就会得到预期的行为。

http://www.cplusplus.com/reference/ctime/ctime/

一个C字符串,包含人类可读格式。

返回的值指向一个内部数组,该数组的有效性或值可以通过任何后续对asctime或ctime的调用进行更改。

返回的值指向一个内部数组,该数组的有效性或值可以通过任何后续对asctime或ctime的调用进行更改。

这正是这里正在发生的事情。该行中对ctime的两个调用中的一个在另一个之前执行,但都在cout打印之前执行。由于它们(可能)返回相同的临时字符缓冲区,所以在cout开始打印时,您会得到相同的结果。