9

Suppose I have a class A that does not inherit from anything, has no virtual methods, and has exactly one variable of type T. Does C++ guarantee sizeof(A) == sizeof(T)?

EDIT:

Also if T were a composite type, would it make a difference?

Thomas Eding
  • 35,312
  • 13
  • 75
  • 106

3 Answers3

7

No, it might be more than sizeof(T) due to padding.

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • 1
    Shouldn't `T` get the same padding? – SLaks May 13 '11 at 15:46
  • 3
    @SLaks, individual variables don't get padding, only the containing structure (or stack space). To be sure `sizeof(A.var) == sizeof(T)` always. – edA-qa mort-ora-y May 13 '11 at 15:50
  • 1
    Have you ever seen this in the wild? Padding is typically used when a struct has more than member and it should be possible to create an array of structs without it's members ending up on unaligned locations. I would put my money on that this is always true, even though I have to dig into the standard in order to prove it. – Lindydancer May 13 '11 at 16:07
  • 1
    I'm pretty sure that implementations are allowed to add comedy padding to the end of structs for absolutely no good reason. Obviously, successful implementations tend not to. – Steve Jessop May 13 '11 at 17:17
  • 4
    @Lindydancer: I hate the `In the real world` quotes. It makes no sense. If you program by what is `Currently` the real world situation rather then by the `standard` your code is just broken. Normally because your `real world` is usually very limited does not take into account future research and ultimately will cause cause a catastrophic failure that will be practically imposable to debug when you port the code to a new architecture/compiler were your assumptions no longer hold. – Martin York May 13 '11 at 17:17
  • Give a example for 'might be' – Huang F. Lei May 13 '11 at 17:35
  • 2
    Any optimizations which results in `A` benefiting from padding would apply equally well to `T`, so this hypothetical compiler would almost certainly do so, resulting in `sizeof(T) == sizeof(A)`. I see RTTI being a much more "plausible" cause for seemingly arbitrary size increases. If a compiler tacks type information of some sort onto some/all non-polymorphic types in order to optimize the polymorphic cases, things could get odd. – Dennis Zickefoose May 13 '11 at 21:02
  • However, the standard doesn't just let the compiler do whatever it wants with structures; it places several limitations on how they are laid out, and places even more limitations on how POD types are laid out. C++11 goes even further. If `T` is a fairly simple type [a primitive, for instance], the freedom to apply these hypothetical optimizations is small. I say make the assumption, and throw a `static_assert(sizeof(T) == sizeof(A));` somewhere on the off chance it stops being safe. – Dennis Zickefoose May 13 '11 at 21:13
  • @Dennis: indeed, code that fails to compile on some obscure strange platform is a lot better than code that compiles and has UB on some obscure strange platform. – Steve Jessop May 14 '11 at 10:59
  • @Naveen: sure about this? `A` and `T` are guaranteed to have the same alignment requirements, which means that padding is, by definition, unnecessary . I can't remember the exact wording, but is the compiler allowed to insert padding where it's not necessary? It might be, but it would be absurd for this to happen in practice. – jalf Jul 29 '12 at 10:27
2

I don't think it explicitly guarantees it, but I don't think it would ever be different.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 2
    @John what makes you think so? If you have some evidence then I will definitely delete this answer. – Seth Carnegie May 13 '11 at 15:56
  • @Seth: Actually, I'm reconsidering this assertion. – John Dibling May 13 '11 at 16:07
  • 2
    @John: I would really like to see an environment where this is true! I don't see any reason why a compiler would add padding to a struct/class with exactly one member. – Lindydancer May 13 '11 at 16:09
  • @Lindy: Consider if that one member is not a primitive type. That's where my mind went. – John Dibling May 13 '11 at 16:22
  • 3
    @John: How would that increase padding? The type itself would already have its padding. (Talking pragmatically, of course.) – GManNickG May 13 '11 at 16:29
  • @John I just tried it with a couple types from the STL and they were all the same (MSVC++ 2010, Windows 7). – Seth Carnegie May 13 '11 at 16:45
  • 2
    Making the assumption will break somthing when the compiler people invite super optimization X that makes your assumption no longer valid. Just because `you` can't think of a logical reason does not mean anything. Unless you are a compiler engineer you literally have very little understanding of even a fraction of the real world tricks they are performing underneath the surface. – Martin York May 13 '11 at 17:21
  • 1
    @Martin: C++ is already published many years, even compiler people invite some "super optimization X", you can still use the old version of compiler to compile your "assumption". I am sure they don't dare to update all versions of compiler to break customer's code only for adding a "supper optimization X". – Huang F. Lei May 13 '11 at 17:48
  • 3
    @Huang F. Lei: That's exactly what they do because they expect people to write standard compliant code that makes no assumptions. Writing code make assumptions on how the compiler works is silly unprofessional and just asking for trouble. – Martin York May 13 '11 at 18:09
-1

I think C++ should guarantee sizeof(A) == sizeof(T).

Consider bellow situation, C++ should make it works just like in C:

A a[10];
T t[10];

A * ap = (A *) t;
T * tp = (T *) a;

memcpy(ap, tp, sizeof(*ap));
Huang F. Lei
  • 1,835
  • 15
  • 23