Here's some weirdness with empty structures being treated differently (i.e. different offsets, sizes, binary layout) between C and C++.
struct foo { };
struct foo2 { };
struct bar
{
foo var1;
int var2;
};
struct bar2 : foo
{
int var2;
};
struct bar3 : foo
{
int a,b;
};
struct bar4 : foo
{
bar3 var3;
};
struct bar5 : foo, foo2
{
int d;
};
struct bar6 : bar2, foo2
{
int d;
};
struct bar7 : foo2
{
bar2 v;
int d;
};
C89
sizeof(foo) == 0
sizeof(bar) == 4
rest are C++-only (inheritance)
C99
empty "struct foo" not allowed
sizeof(bar) == 4
rest are C++-only (inheritance)
C++ Standard (comments show where the C++
standard requires padding / wasted space)
sizeof(foo) == 1 (* typical value)
-- sizeof(foo) != 0 (usually 1 but
possibly some other value that is
compiler/alignment dependent)
sizeof(bar) == 8
!!! Wasting space on empty struct !!!
C++-only:
sizeof(bar2) == 4
sizeof(bar3) == 8
OK - no padding before first member
sizeof(bar4) == 12
!!! pad before first member due to
identical-empty-base conflict between
base class and first member
sizeof(bar5) == 4
sizeof(bar6) == 8
sizeof(bar7) == 8
GCC C++ (PS3): -- Fully compliant to Standards
with best-allowed empty-base-optimization
sizeof(foo) == 1
sizeof(foo2) == 1
sizeof(bar) == 8
sizeof(bar2) == 4
sizeof(bar3) == 8
sizeof(bar4) == 12
sizeof(bar5) == 4
sizeof(bar6) == 8
sizeof(bar7) == 8
MSVC++
sizeof(foo) == 1
sizeof(foo2) == 1
sizeof(bar) == 8
sizeof(bar2) == 4
sizeof(bar3) == 8
sizeof(bar4) == 8
!!! NONCOMPLIANCE !!! -- sizeof() should be 12
- overaggressive empty-base-optimization
(bar4::foo not allowed to resolve to
same address as bar4.var3::foo)
sizeof(bar5) == 8
Wasted Space - standard allows
empty-base-optimization of foo & foo2
sizeof(bar6) == 12
Wasted Space - standard allows
empty-base-optimization of foo & foo2
sizeof(bar7) == 8
-------------------
struct NullCounterNoInit
{
FORCEINLINE void Inc() { }
};
struct ThreadOwnedCounter
{
UINT32 m_nCountVal;
FORCEINLINE UINT32 Inc() { return(++m_nCountVal); }
};
template
class Test1
{
TCounter counter;
int foo;
int ReadFoo() { counter.Inc(); return(foo); }
}
template
class Test2 : TCounter
{
int foo;
int ReadFoo() { TCounter::Inc(); return(foo); }
}
sizeof(Test1) == 8
!!! Wasting space on empty struct !!!
sizeof(Test2) == 4
sizeof(Test1) == 8
sizeof(Test2) == 8
No comments:
Post a Comment