Aliasing is the main optimization issue with pass-by-const-reference functions that take multiple arguments; this has been pointed out in answers to similar questoins. However, this particular answer also seems to suggest that the compiler can make more assumptions about a single-argument pass-by-value function than an otherwise identical pass-by-const-reference function.
This would imply that pass-by-value is the preferred strategy for small objects. While this seems like perfectly sound logic for an argument of a non-class type or a type with a constexpr
copy constructor, I fail to see how these assumptions could be extended to an argument that does not meet these requirements. Take the following example:
foo.h
#ifndef FOO_H
#define FOO_H
struct Foo {
int i;
Foo(int i);
Foo(const Foo &other);
~Foo();
};
void incrementNewestFoo();
#endif
foo.cpp
#include "foo.h"
#include <algorithm>
#include <vector>
std::vector<Foo *> foos;
Foo::Foo(int i) : i(i) {
foos.push_back(this);
}
Foo::Foo(const Foo &other) : i(other.i) {
foos.push_back(this);
}
Foo::~Foo() {
foos.erase(std::find(foos.cbegin(), foos.cend(), this));
}
void incrementNewestFoo() {
foos.back()->i += 1;
}
main.cpp
#include "foo.h"
#include <iostream>
using namespace std;
void passByValue(Foo foo) {
cout << foo.i << endl;
incrementNewestFoo();
cout << foo.i << endl;
}
void passByConstReference(const Foo &foo) {
cout << foo.i << endl;
incrementNewestFoo();
cout << foo.i << endl;
}
int main() {
Foo foo(0);
passByValue(foo);
passByConstReference(foo);
}
As far as I'm aware, the behavior of main()
is well-defined according to the C++ standard. According to the previously linked answer, the most valuable assumption to be made about the pass-by-value function is that the value of i
will not change between reads in most cases. However, it appears to me as though this assumption is invalid for any call to a function whose definition resides in another compilation unit (except for const
member functions for which the pass-by-const-reference function can make the same assumption anyway). Perhaps I am missing something?