将打包结构成员的引用传递给模板。海湾合作委员会错误?
Passing reference of packed struct member to template. gcc bug?
我在将结构成员传递给模板函数时遇到问题。该函数的目标是获取成员的地址和大小。这是一个简单的例子:
这是结构体。具有packed属性。
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;
}
问题:当属性((packed));已设置(如示例中所示)
模板函数接收到错误的成员地址:
输出:
struct address is: 0x7fff735bb4e0
elem4 address is: 0x7fff735bdbfa
address inside func: 0x7fff735bb4dc
如果我删除 "packed" 属性,一切正常。
没有错误也没有警告(即使使用 -Wall -Wextra),但没有将正确的地址传递给函数。
我读了这个:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
并发现获取对压缩结构成员的引用时出现问题。
有趣的是,在我的模板函数中用 T& 替换 const T& 会产生错误消息:
error: cannot bind packed field ‘testdata.TestStruct::elem4’ to ‘int&’
所以,我有 2 个问题:
为什么压缩结构成员不能作为 const 引用传递,而它们的地址可以作为指针传递
const T& 情况下发生了什么?没有错误,没有警告,但是传递给函数的地址不正确。我们知道,引用地址就是变量的地址,引用指向.
你的两个问题都在你发布的 link 中得到了回答。
1.为什么压缩结构成员不能作为常量引用传递,而它们的地址可以作为指针传递
Gabriel M. Beddingfield 在 his comment 中写道:
All assignments of obj.s to type short& and short* are incorrect, and ideally they would all result in compiler errors.
The C++ spec (C++03, Sects. 3.9, 3.9.1, 3.9.2) are very clear that T and "pointer to T" have implementation-specific alignment requirements. If you have a "pointer to T" then you may assume that it meets the alignment requirements. I'm sure the C spec has similar language.
我只能添加 C++14 标准中相应的引用 ([basic.align]/1):
Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier
最重要的是,即使获取打包结构成员的地址也应该是错误的。
2。在 const T& 情况下会发生什么?没有错误,没有警告,但是传递给函数的地址不正确。我们知道,引用地址就是变量的地址,引用指向.
乔纳森·维克利 wrote:
A const-reference causes a temporary to be created, you didn't bind to the packed field
最重要的是,不能将非常量引用绑定到打包的结构字段本身并不是错误,错误是您可以同时获取它的地址。编译器应该允许或不允许两者。
我在将结构成员传递给模板函数时遇到问题。该函数的目标是获取成员的地址和大小。这是一个简单的例子:
这是结构体。具有packed属性。
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;
}
问题:当属性((packed));已设置(如示例中所示) 模板函数接收到错误的成员地址:
输出:
struct address is: 0x7fff735bb4e0
elem4 address is: 0x7fff735bdbfa
address inside func: 0x7fff735bb4dc
如果我删除 "packed" 属性,一切正常。 没有错误也没有警告(即使使用 -Wall -Wextra),但没有将正确的地址传递给函数。
我读了这个:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
并发现获取对压缩结构成员的引用时出现问题。 有趣的是,在我的模板函数中用 T& 替换 const T& 会产生错误消息:
error: cannot bind packed field ‘testdata.TestStruct::elem4’ to ‘int&’
所以,我有 2 个问题:
为什么压缩结构成员不能作为 const 引用传递,而它们的地址可以作为指针传递
const T& 情况下发生了什么?没有错误,没有警告,但是传递给函数的地址不正确。我们知道,引用地址就是变量的地址,引用指向.
你的两个问题都在你发布的 link 中得到了回答。
1.为什么压缩结构成员不能作为常量引用传递,而它们的地址可以作为指针传递
Gabriel M. Beddingfield 在 his comment 中写道:
All assignments of obj.s to type short& and short* are incorrect, and ideally they would all result in compiler errors.
The C++ spec (C++03, Sects. 3.9, 3.9.1, 3.9.2) are very clear that T and "pointer to T" have implementation-specific alignment requirements. If you have a "pointer to T" then you may assume that it meets the alignment requirements. I'm sure the C spec has similar language.
我只能添加 C++14 标准中相应的引用 ([basic.align]/1):
Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier
最重要的是,即使获取打包结构成员的地址也应该是错误的。
2。在 const T& 情况下会发生什么?没有错误,没有警告,但是传递给函数的地址不正确。我们知道,引用地址就是变量的地址,引用指向.
乔纳森·维克利 wrote:
A const-reference causes a temporary to be created, you didn't bind to the packed field
最重要的是,不能将非常量引用绑定到打包的结构字段本身并不是错误,错误是您可以同时获取它的地址。编译器应该允许或不允许两者。