nev*_*stn 5 c++ gcc ternary-operator clang++
我对这里发生的事情有一个模糊的想法......它与此有关,但我想知道为什么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;
}
Run Code Online (Sandbox Code Playgroud)
gcc输出(测试高达4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
Run Code Online (Sandbox Code Playgroud)
clang 3.7.0输出:
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
begin: 0x7ffed7b6bb97
ref: 0x7ffed7b6bb97
Run Code Online (Sandbox Code Playgroud)
我今天在另一个问题中的回答详细介绍了您的案例。我将避免重复自己,只是进行总结。
如果我们分解出模板,就会有两种情况。情况1:
const char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
Run Code Online (Sandbox Code Playgroud)
条件运算符的第二个和第三个操作数都是“类型的左值const char”,因此结果是const char指定所选操作数的“类型的左值”。最后,const char &直接绑定到“类型的左值const char”,因此&me== &a。
对于情况2:
char whatever = 'c';
const char a = 'a';
const char & me = (true ? a : whatever);
Run Code Online (Sandbox Code Playgroud)
第二个和第三个操作数是“类型的左值char”和“类型的左值const char”。其结果是const char指定所选操作数的“类型左值”。和以前一样,const char &me直接绑定到类型 的左值const char,因此&me == &a。
如果编译器在任一情况下打印不同的地址me,a则这是一个编译器错误。
| 归档时间: |
|
| 查看次数: |
142 次 |
| 最近记录: |