The following code tries to rename
an existing file to a new location. In my environment, the rename fails because source and destination are on different mount points.
Given the failure, why is the value of errno
reported as 0
in version2()
? I can't imagine errno
not being set synchronously with rename()
, and I imagined that operands to std::ostream::operator<<
were evaluated in left-to-right order. If that were true, shouldn't errno
have acquired its nonzero value from rename
's failure before it was passed to the output operator?
Obviously reality is not matching what I imagined; can someone explain the order of evaluation or other relevant reasons why version2
outputs an errno
value of 0
?
The code:
// 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;
}
Compilation & output:
> g++ --version && g++ -g main.cpp && ./a.out
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
version1
-1
18: Invalid cross-device link
version2
-1: 0: Success
(I searched SO for existing questions addressing this, but either none exist, or my search phrasings weren't adequate matches for anything existing)
Update:
I think this question resolves down to "what is the order of evaluation of the operands to the output operator?" in which case, according to Order of evaluation of arguments using std::cout the answer is "unspecified."
In the spirit of academic learning (and generating information useful to the community), I'm curious if anyone is aware of the history why the order of evaluation of output stream operands is undefined: It seems intuitive that they should be evaluated left-to-right...?