4

运行以下代码:

  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 中的流变得奇怪?

4

4 回答 4

7

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

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

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

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

在您的示例中,在第 6 行,ctime(&t1)首先评估,然后ctime(&t)覆盖字符串(首先评估的是未指定的,并且编译器通常以相反的顺序评估(通常,并非总是))。

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

于 2013-07-10T15:43:50.800 回答
3

该函数ctime返回一个static字符串缓冲区 - 所以每次返回的字符串都是完全相同的字符串),这意味着在同一行上多次调用它会产生未定义的行为(因为 C 和 C++ 标准没有说明调用的顺序制作)。

解决方案是调用两个不同的语句(with ;between),或使用可重入安全的变体,您传入缓冲区以存储结果),例如ctime_r

于 2013-07-10T15:47:23.263 回答
1

这里的问题是ctime()使用内部分配的 char 数组,每次调用都会修改ctime().

这里的另一个问题是您ctime()的 s 可以在该表达式中以任何顺序进行评估。所以这里发生的事情是第 6 行上的它们都被评估了,但显然第二个被评估了。然后运算符从左到右应用,但两个调用ctime都已经被评估,最左边的一个是之后完成的,现在两个字符串都指向同一个东西。

如果您将它们放在不同的行上,您将获得预期的行为。

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

包含人类可读格式的日期和时间信息的 C 字符串。

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

于 2013-07-10T15:45:37.733 回答
0

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

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

于 2013-07-10T15:45:20.743 回答