Here are answers about argument evaluation order - In short: the order is not specified in standard and may be different per platform, compiler and calling convention.
But I wanted to test it so here are results for Cygwin GCC:
#include <iostream>
#include <memory>
using namespace std;
void print(int* p) {
cout << (p == nullptr ? "null" : "valid") << endl; }
void foo(int* p, unique_ptr<int> u) {
print(p); }
void bar(unique_ptr<int> u, int* p) {
print(p); }
__stdcall void foo2(int* p, unique_ptr<int> u) {
print(p); }
__stdcall void bar2(unique_ptr<int> u, int* p) {
print(p); }
__cdecl void foo3(int* p, unique_ptr<int> u) {
print(p); }
__cdecl void bar3(unique_ptr<int> u, int* p) {
print(p); }
int main() {
unique_ptr<int> p(new int(1)), q(new int(2));
foo(p.get(), move(p)); bar(move(q), q.get());
unique_ptr<int> p2(new int(1)), q2(new int(2));
foo2(p2.get(), move(p2)); bar2(move(q2), q2.get());
unique_ptr<int> p3(new int(1)), q3(new int(2));
foo3(p3.get(), move(p3)); bar3(move(q3), q3.get());
}
Output:
null
valid
null
valid
null
valid
Surprise is that I could not force it to change the order even when I used __stdcall
and __cdecl
.
EDIT: Same test with MSVC 2012 (__stdcall/__cdecl moved before names), same result!