为什么errno失败时意外地为0?

时间:2018-10-08 21:04:21

标签: c++ errno

以下代码尝试将现有文件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,答案是“未指定”。 本着学术学习的精神(并生成对社区有用的信息),我很好奇是否有人知道历史为什么未定义输出流操作数的评估顺序:似乎直观应该从左到右对它们进行评估...?

0 个答案:

没有答案