运行以下代码:
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中变得奇怪?
答案 0 :(得分:7)
http://www.cplusplus.com/reference/ctime/ctime/
返回的值指向内部数组,其有效性或值可能会被后续调用
asctime
或ctime
更改。
http://en.cppreference.com/w/cpp/chrono/c/ctime
字符串可以在
std::asctime
和std::ctime
之间共享,可能会在每次调用任何这些函数时被覆盖。
在您的示例中,在第6行,首先评估ctime(&t1)
,然后覆盖字符串的ctime(&t)
(首先评估的是未指定的,编译器通常以相反的顺序进行评估(经常,并非总是如此)。
TL; DR:阅读文档可能会有所帮助。
答案 1 :(得分:3)
函数ctime
返回一个static
字符串缓冲区 - 所以返回的字符串每次都是完全相同的字符串),这意味着在同一行上多次调用它会产生未定义的行为(因为C和C ++标准没有说明调用的顺序是什么。
解决方案是调用两个不同的语句(两者之间有;
),或者使用reentrant-safe变体,在这里传入缓冲区以存储结果),例如: ctime_r
答案 2 :(得分:1)
这里的问题是ctime()
使用内部分配的char数组,每次调用ctime()
时都会对其进行修改。
这里的另一个问题是您的ctime()
可以在该表达式中以任何顺序进行评估。所以这里发生的是第6行的两个都被评估,但显然第二个是第二个。然后从左到右应用运算符,但是对ctime
的两个调用都已经过评估,最左边的调用是在之后完成的,现在两个字符串都指向相同的东西。
如果您将它们放在不同的行上,您将获得预期的行为。
http://www.cplusplus.com/reference/ctime/ctime/
包含a中日期和时间信息的C字符串 人类可读的格式。
返回的值指向其有效性或值的内部数组 任何后来对asctime或ctime的调用都可能会改变。
答案 3 :(得分:0)
返回的值指向其有效性或值的内部数组 任何后来对asctime或ctime的调用都可能会改变。
这正是这里发生的事情。在该行中对ctime的两次调用之一在另一行之前执行,但在cout可以打印它们之前都执行。由于它们(可能)返回相同的临时字符缓冲区,因此在cout进入打印时会得到相同的结果。