5

Are the attributes of a struct inherited in C++

eg:

struct A {
    int a;
    int b;
}__attribute__((__packed__));

struct B : A {
    list<int> l;
};

will the inherited part of struct B (struct A) inherit the packed attribute?

I cannot add an a attribute((packed)) to struct B without getting a compiler warning:

ignoring packed attribute because of unpacked non-POD field

So I know that the entire struct B will not be packed, which is fine in my use case, but I require the fields of struct A to be packed in struct B.

squater
  • 189
  • 1
  • 2
  • 8

2 Answers2

5

Will the inherited part of struct B (struct A) inherit the packed attribute?

Yes. The inherited part will still be packed. But the pack attribute itself is not inherited:

#include <stdio.h>

#include <list>
using std::list;

struct A {
    char a;
    unsigned short b;
}__attribute__((__packed__));

struct B : A {
    unsigned short d;
};

struct C : A {
    unsigned short d;
}__attribute__((__packed__));

int main() {
   printf("sizeof(B): %lu\n", sizeof(B));
   printf("sizeof(C): %lu\n", sizeof(C));

   return 0;
}

When called, I get

sizeof(B): 6
sizeof(C): 5

I think your warning comes from the list<> member which is a non-POD type and itself not packed. See also What are POD types in C++?

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • @Andreas - ye like Didier said, I cannot pack struct B because I have a list variable in it. Thanks for your suggestion, but the size difference between struct B and C, could be because of variable 'd'. I want to know if variable 'a' and 'b' in struct B are packed, and always will be packed – squater Sep 21 '12 at 13:13
  • Yeah - just reread your question based on some other answers - so, yes, the *inherited part* is still packed, but the packed attribute itself is not inherited. If required you need to rephrase it in the sub structure, which only works if there are no non-POD objects in it. – Andreas Fester Sep 21 '12 at 13:14
  • @squater: You could write a test case checking the offset of the "b" member within "struct B", and check if it is at the expected position. However, the offsetof macro which exists to do this check is not supported in C++ sub classes/structures, see also [What is wrong with this use of offsetof?](http://stackoverflow.com/questions/3129916/what-is-wrong-with-this-use-of-offsetof). So, the question should probably more be like "How to ensure that a member is aligned at the expected offset". – Andreas Fester Sep 21 '12 at 13:39
4

Yes, the members of A will be packed in struct B. It must be this way, otherwise it would break the whole point of inheritance. For example:

std::vector<A*> va;
A a;
B b;
va.push_back(&a);
vb.push_back(&b);

// loop through va and operate on the elements. All elements must have the same type and behave like pointers to A.
tenfour
  • 36,141
  • 15
  • 83
  • 142
  • 1
    After going the hard way of trying it and looking at assembly, I suddenly thought of the inheritance situation... Brainfart. – BoBTFish Sep 21 '12 at 13:13