lundi 30 mars 2015

Passing reference of packed struct member to template. gcc bug?


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:


http://ift.tt/1xO5ke8


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:




  1. Why cannot packed-struct members be passed as const references, when their address can be passed as pointer




  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.






Aucun commentaire:

Enregistrer un commentaire