问题
I have a vague idea of what's going on here... and it has to do with this but I'm wondering why clang++ and g++ handle this differently. Where is the undefined behaviour arround here? Note: this has nothing to do with templates - I just use them to make the example more compact. It's all about the type of whatever
.
#include <iostream>
#include <vector>
template <typename T>
void test()
{
T whatever = 'c';
const char a = 'a';
std::cout << "begin: " << (void*)&a << std::endl;
const char & me = (true ? a : whatever);
std::cout << "ref: " << (void*)&me << std::endl;
}
int main(int argc, char**argv)
{
test<const char>();
test<char>();
return 0;
}
gcc output (tested up to 4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
clang 3.7.0 output:
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
回答1:
My answer from this other question from today covers your cases in detail. I'll avoid repeating myself and just summarize.
If we factor out the templates you have two cases. Case 1:
const char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
The second and third operands of the conditional operator are both "lvalue of type const char
", so the result is "lvalue of type const char
" designating the selected operand. Finally, const char &
binds directly to "lvalue of type const char
", so &me
== &a
.
For case 2:
char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
The second and third operand are "lvalue of type char
" and "lvalue of type const char
". The result of this is "lvalue of type const char
" designating the selected operand. As before, const char &me
binds directly to an lvalue of type const char
, so &me == &a
.
If a compiler prints different addresses for me
and a
in either case, it is a compiler bug.
来源:https://stackoverflow.com/questions/40160904/difference-on-address-of-const-reference-to-ternary-operator-between-clang-and-g