以下代码尝试将现有文件rename
移到新位置。在我的环境中,重命名失败,因为源和目标位于不同的安装点。
鉴于失败,为什么在errno
中将0
的值报告为version2()
?我无法想象errno
不会与rename()
同步设置,并且我想象到std::ostream::operator<<
的操作数是按从左到右的顺序求值的。如果是这样,errno
是否应该在传递给输出运算符之前从rename
的失败中获取其非零值?
显然,现实与我的想象不符;有人可以解释评估的顺序或其他相关原因,为什么version2
输出errno
的{{1}}值?
代码:
0
编译和输出:
// main.cpp
// Prereq: "./" and "/tmp" are on different mount points.
// Prereq: "./foo.txt" exists.
#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>
void version1()
{
std::cout << __FUNCTION__ << std::endl;
std::cout << rename( "./foo.txt", "/tmp/bar.txt" ) << std::endl;
std::cout << errno << ": " << strerror( errno ) << std::endl;
}
void version2()
{
std::cout << __FUNCTION__ << std::endl;
std::cout << rename( "./foo.txt", "/tmp/bar.txt" ) << ": "
<< errno << ": " << strerror( errno ) << std::endl;
}
int main( int argc, char* argv[] )
{
errno = 0;
version1();
errno = 0;
version2();
return 0;
}
(我在SO中搜索了可解决此问题的现有问题,但要么不存在,要么我的搜索措词不足以匹配任何现有问题)
更新:
我认为这个问题可以归结为“对输出运算符的操作数求值顺序是什么?”在这种情况下,根据Order of evaluation of arguments using std::cout,答案是“未指定”。
本着学术学习的精神(并生成对社区有用的信息),我很好奇是否有人知道历史为什么未定义输出流操作数的评估顺序:似乎直观应该从左到右对它们进行评估...?