问题描述
我遇到了一个问题,将struct成员传递给了模板函数。该函数的目标是获取成员的地址和大小。这是简单的示例:
这是结构。
struct TestStruct {
unsigned char elem1;
无符号字符elem2;
uint64_t elem3;
char buf [10000];
int elem4;
无符号字符elem5;
}
__attribute __((打包));
这是模板函数,应获取成员地址
template< typename T>
void addData(const T& val)
{
printf(函子内部的地址:%p \n,& val);
}
int main(int argc,char * argv [])
{
TestStruct testdata;
testdata.elem4 = 0;
printf(结构地址为:%p \n,& testdata);
printf( elem4地址为:%p \n,& testdata.elem4);
addData(testdata.elem4);
返回0;
}
问题:属性(打包) );设置(如示例中一样)
模板函数接收到错误的成员地址:
输出:
结构地址为:0x7fff735bb4e0
elem4地址为:0x7fff735bdbfa
func内部的地址:0x7fff735bb4dc
如果删除 packed属性,一切正常。
没有错误也没有警告(即使使用-Wall -Wextra也是如此),但是没有将正确的地址传递给该函数。
我读到以下内容:
,发现存在问题,引用了压缩结构成员。
足够有趣,替换const T&与T&在我的模板函数中,产生错误消息:
错误:无法将压缩字段'testdata.TestStruct :: elem4'绑定到' int&'
所以,我有2个问题:
-
为什么不能将打包结构成员的地址作为指针传递,则不能将其作为const引用传递
-
const T&中会发生什么案件?没有错误,没有警告,但是错误的地址被传递给该函数。众所周知,引用的地址就是变量的地址,引用指向该变量。
您发布的链接都回答了您的两个问题。
1。为什么可以将打包结构成员的地址作为指针传递而不能将其作为const引用传递?
Gabriel M. Beddingfield在:
我只能在其中添加C ++ 14标准中的相应引号([basic.align ] / 1):
其底线是,即使添加一个压缩结构成员也应该是一个错误。 / p>
2。 const T&中会发生什么案件?没有错误,没有警告,但是错误的地址被传递给该函数。众所周知,引用地址就是变量的地址,引用指向该变量。
Jonathan Wakely :
最重要的是,这不是错误它本身不能将非const引用绑定到打包的struct字段,所以一个错误是您可以同时获取它的地址。编译器应允许或禁止两者。
I encountered a problem, passing struct member to a template function. The function's goal is to take the address and size of the member. Here is simple example:
This is the struct. It has packed attribute.
struct TestStruct {
unsigned char elem1;
unsigned char elem2;
uint64_t elem3;
char buf[10000];
int elem4;
unsigned char elem5;
}
__attribute__ ((packed));
this is the template function, which should get a member's address
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;
}
The problem: When attribute ((packed)); is set (like in the example)the template function receives wrong address of the member:
Output:
struct address is: 0x7fff735bb4e0
elem4 address is: 0x7fff735bdbfa
address inside func: 0x7fff735bb4dc
If I remove the "packed" attribute, everything is OK.There is no error and no warning (even with -Wall -Wextra), but not the right address is passed to the function.
I read this:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
and found that there is an issue, getting references to packed-struct members.Interesting enough, replacing const T& with T& in my template function, produces the error message:
error: cannot bind packed field ‘testdata.TestStruct::elem4’ to ‘int&’
So, I have 2 questions:
Why cannot packed-struct members be passed as const references, when their address can be passed as pointer
What happens in the const T& case? There is no error, no warning, but the incorrect address is passed to the function. As we know, the address of reference is the address of the variable, the reference points to.
Both of your questions are answered at the link you posted.
1. Why cannot packed-struct members be passed as const references, when their address can be passed as pointer
Gabriel M. Beddingfield wrote in his comment:
I can only add to this the corresponding quote from C++14 standard ([basic.align]/1):
The bottom line of it is that even taking an addres of a packed struct member should be an error.
2. What happens in the const T& case? There is no error, no warning, but the incorrect address is passed to the function. As we know, the address of reference is the address of the variable, the reference points to.
Jonathan Wakely wrote:
The bottom line is that it's not a bug itself that you can't bind a non-const reference to a packed struct field, a bug is that at the same time you can take an address of it. The compiler should either allow or disallow both.
这篇关于将打包的struct成员的引用传递给模板。 gcc错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!