I've just found something really weird, check out this code:
#include <cstring>
#include <cstdio>
#include <utility>
#include <vector>
using namespace std;
class A {
public:
int n = 0;
A(const char* p) { n = strlen(p); };
A(A const&) = delete;
void operator=(A const&) = delete;
};
void F(vector<pair<const char*, const A&>> v) {
printf("F\n");
for(vector<pair<const char*, const A&>>::iterator it = v.begin();it!=v.end();++it) printf(" '%s': %p %i\n", it->first, &it->second, it->second.n);
};
int main(int, char**) {
F({
{ "A", "A" },
{ "B", "BB" },
{ "C", "CCC" },
{ "D", "DDDD" }
});
};
Now compile it with clang++ -std=c++11 -Wall -Wextra -Wpedantic -O0 main.cc -o main
, or something similar (with optimization disabled).
And you should see an output like this:
F
'A': 0x7fff57a0b988 1
'B': 0x7fff57a0b9d0 2
'C': 0x7fff57a0ba18 3
'D': 0x7fff57a0ba60 4
Which is nice, the compiler automatically creates the vector object and the corresponding A&
references, which are all different.
Now, compile it with clang++ -std=c++11 -Wall -Wextra -Wpedantic -O1 main.cc -o main
, notice how I just added the lowest level of optimization.
And you would see,
F
'A': 0x7fff5ac54b30 1629262454
'B': 0x7fff5ac54b30 1629262454
'C': 0x7fff5ac54b30 1629262454
'D': 0x7fff5ac54b30 1629262454
that all parameters reference the same A&
object, which I find wrong.
Here are my compiler details:
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
Is this expected behavior? Is this a compiler bug?
Update:
As pointed out by Matt McNabb, vectors and initializer_lists are not designed to work with const references (although, it compiles fine in clang). However, when writing the same function as void F(vector<pair<char*, A&&>>) {}
the error still persists.