clang 和 gcc 之间对三元运算符的 const 引用地址的差异
Difference on address of const reference to ternary operator between clang and gcc
我对这里发生的事情有一个模糊的想法......它与 this 有关,但我想知道为什么 clang++ 和 g++ 以不同的方式处理这个问题。这里的未定义行为在哪里?注意:这与模板无关——我只是使用它们来使示例更紧凑。都是关于 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 输出(测试到 4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
clang 3.7.0 输出:
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
我 的回答详细介绍了您的案例。我会避免重复自己,只是总结一下。
如果我们分解出模板,您有两种情况。案例 1:
const char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
条件运算符的第二个和第三个操作数都是"lvalue of type const char
",所以结果是"lvalue of type const char
"指定选择的操作数。最后,const char &
直接绑定到 "lvalue of type const char
",所以 &me
== &a
.
对于案例 2:
char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
第二个和第三个操作数是"lvalue of type char
"和"lvalue of type const char
"。其结果是 "lvalue of type const char
" 指定选定的操作数。和以前一样,const char &me
直接绑定到 const char
类型的左值,所以 &me == &a
.
如果编译器为 me
和 a
打印不同的地址,这就是编译器错误。
我对这里发生的事情有一个模糊的想法......它与 this 有关,但我想知道为什么 clang++ 和 g++ 以不同的方式处理这个问题。这里的未定义行为在哪里?注意:这与模板无关——我只是使用它们来使示例更紧凑。都是关于 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 输出(测试到 4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
clang 3.7.0 输出:
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
我
如果我们分解出模板,您有两种情况。案例 1:
const char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
条件运算符的第二个和第三个操作数都是"lvalue of type const char
",所以结果是"lvalue of type const char
"指定选择的操作数。最后,const char &
直接绑定到 "lvalue of type const char
",所以 &me
== &a
.
对于案例 2:
char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
第二个和第三个操作数是"lvalue of type char
"和"lvalue of type const char
"。其结果是 "lvalue of type const char
" 指定选定的操作数。和以前一样,const char &me
直接绑定到 const char
类型的左值,所以 &me == &a
.
如果编译器为 me
和 a
打印不同的地址,这就是编译器错误。