将压缩结构成员的引用传递给模板。 gcc bug?

时间:2015-03-30 07:02:31

标签: c++ struct reference

我遇到了一个问题,将struct成员传递给模板函数。该功能的目标是获取成员的地址和大小。这是一个简单的例子:

这是结构。它有打包属性。

struct TestStruct {
    unsigned char       elem1;
    unsigned char       elem2;
    uint64_t            elem3;
    char                buf[10000];
    int                 elem4;
    unsigned char       elem5;
}
__attribute__ ((packed));

这是模板功能,它应该获得会员的地址

template<typename T>
void addData(const T &val)
{
        printf ("address inside func: %p \n",&val);
}

int main(int argc, char *argv[])
{
        TestStruct testdata;
        testdata.elem4 = 0;
        printf ("struct address is:   %p \n",&testdata);
        printf ("elem4  address is:   %p \n",&testdata.elem4);
        addData(testdata.elem4);
        return 0;
}

问题:属性((打包));已设置(如示例中所示) 模板函数接收成员的错误地址:

输出:

struct address is:   0x7fff735bb4e0 
elem4  address is:   0x7fff735bdbfa 
address inside func: 0x7fff735bb4dc

如果我删除&#34;打包&#34;属性,一切都好。 没有错误也没有警告(即使使用-Wall -Wextra),但没有将正确的地址传递给函数。

我读到了这个:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

并发现存在问题,获取对packed-struct成员的引用。 有趣的是,取代const T&amp;与T&amp;在我的模板函数中,生成错误消息:

error: cannot bind packed field ‘testdata.TestStruct::elem4’ to ‘int&’

所以,我有两个问题:

  1. 为什么packed-struct成员不能作为const引用传递,当它们的地址可以作为指针传递时

  2. const T&amp;案件?没有错误,没有警告,但是错误的地址被传递给函数。我们知道,引用的地址是变量的地址,引用指向。

1 个答案:

答案 0 :(得分:3)

您的所有问题都会在您发布的链接中得到解答。

1。为什么pack-struct成员不能作为const引用传递,因为它们的地址可以作为指针传递

Gabriel M. Beddingfield在his comment写道:

  

obj.s的所有分配键入短&amp;和short *是不正确的,理想情况下它们都会导致编译器错误。

     

C ++规范(C ++ 03,Sects.3.9,3.9.1,3.9.2)非常清楚T和“T指针”具有特定于实现的对齐要求。如果你有一个“T指针”,那么你可以认为它符合对齐要求。我确定C规范有类似的语言。

我只能在C ++ 14标准([basic.align] / 1)中添加相应的引用:

  

对象类型具有对齐要求(3.9.1,3.9.2),它对可以分配该类型的对象的地址施加限制。 alignment 是一个实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型对该类型的每个对象强制对齐要求;可以使用对齐说明符

请求更严格的对齐

它的底线是即使采用压缩结构成员的地址也应该是一个错误。

2。 const T&amp; amp;案件?没有错误,没有警告,但是错误的地址被传递给函数。我们知道,引用的地址是变量的地址,引用指向。

Jonathan Wakely wrote

  

const-reference导致创建临时,但未绑定到压缩字段


最重要的是,你不能将非const引用绑定到打包的struct字段本身并不是一个错误,一个错误就是你可以同时获取它的地址。编译器应该允许或禁止两者。