在cout上打印我们的时间时出现了奇怪的C++行为
Weird C++ Behavior while printing our time on cout
运行以下代码:
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/
返回的值指向一个内部数组,其有效性或值可能会被任何后续对
asctime
或ctime
的调用所更改。
http://en.cppreference.com/w/cpp/chrono/c/ctime
该字符串可以在
std::asctime
和std::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开始打印时,您会得到相同的结果。
- 理解boost::asio-async_read在无需读取内容时的行为
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- arr[-1]在c++中的奇怪行为
- 继承期间显示未知行为的子类
- 如何在c++中使用引用实现类似python的行为
- G锁定铸造到基础上会释放模拟行为
- 在C++中对T*类型执行std::move的意外行为
- std::当在256字节边界上写入整数时,流的奇怪行为
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 奇怪的构造函数行为
- 重载运算符new[]的行为取决于析构函数
- 不同语言中相同代码的不同行为
- 处理除以零会导致<csignal>意外行为
- 试图理解类对象的行为
- c++11评估顺序(未定义的行为)
- 从结构寻址时,MMAP变量的行为很奇怪
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 读取文件时运行时的未知行为
- strncpy之后的char数组的错误行为
- 此增量后语句是否会导致未定义的行为?