clang和gcc之间的常量引用到三元运算符的地址的区别 [英] Difference on address of const reference to ternary operator between clang and gcc

查看:173
本文介绍了clang和gcc之间的常量引用到三元运算符的地址的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对这里发生的事情有一个模糊的概念......它与,但我想知道为什么铿锵声++和g ++处理这个不同。这里未定义的行为在哪里?注意:这与模板无关 - 我只是用它们来使示例更加紧​​凑。这是关于类型的任何

  #include< iostream> ; 
#include< vector>

模板< typename T>
void test()
{
T whatever ='c';


const char a ='a';

std :: cout<< begin:<< (void *)& a<<的std :: ENDL;

const char&我=(true?a:无论);

std :: cout<< ref:<< (void *)& amp;<<的std :: ENDL;


int main(int argc,char ** argv)
{

test< const char>();
test< char>();

返回0;

$ / code $ / pre
$ b $ gcc输出(测试到4.9.3):

  begin:0x7fffe504201f 
ref:0x7fffe504201f
begin:0x7fffe504201e
ref:0x7fffe504201f

铿锵3.7.0输出:

  begin:0x7ffed7b6bb97 
ref:0x7ffed7b6bb97
begin:0x7ffed7b6bb97
ref:0x7ffed7b6bb97


解决方案

我的回答来自详细介绍了您的案例。我会避免重复自己,只是总结。



如果我们将模板分解出来,您有两种情况。案例1:

  const char whatever ='c'; 
const char a ='a';
const char&我=(true?a:无论);

条件运算符的第二个和第三个操作数都是左值类型 const char ,所以结果是 const char 类型的左值,指定选定的操作数。最后, const char& 直接绑定到 const char 的左值,所以 & me == & a



p>

  char whatever ='c'; 
const char a ='a';
const char&我=(true?a:无论);

第二个和第三个操作数是类型 char 和左值类型 const char 。这样做的结果是指定所选操作数的 const char 类型的左值。和以前一样, const char& me 直接绑定到 const char 类型的左值,所以& me ==& a



如果编译器为 me打印不同的地址 a ,这是一个编译器错误。


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

解决方案

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.

这篇关于clang和gcc之间的常量引用到三元运算符的地址的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆