Topic: Sizeof and inheritance


Author: jkanze@otelo.ibmmail.com
Date: 1998/03/18
Raw View
In article <6emr9c$ebu@engnews1.Eng.Sun.COM>,
  clamage@Eng.Sun.COM wrote:

> I don't think there is any portable way to find the "size" of a type
> that doesn't include such padding, and it isn't clear to me that the
> concept has any useful meaning in a portable program.
>
> For example, you might be tempted to try this:
>  void CheckSize()
>  {
>   MyType m;
>   char c; // assume c doesn't get aligned
>
>   if( labs((char*)&m - &c) != sizeof(m) )
>    cout << "Gotcha!";
>  }
> ... the idea being that maybe you could detect when sizeof(m) is not
> the same as the space actually occupied by a single object.
>
> But comparing or subtracting addresses of unrelated objects has
> undefined results, so code like this is not even required to compile,
> let alone produce a useful result.

Even if it does compile and give defined results (as is in fact the case
on most machines with linear addressing), and ignoring for the moment
that the compiler has no constraints concerning the ordering of the
local variables (c may be physically before m), I don't think that the
compiler could place c anywhere in the address range [&m..&m+1).
Isn't the following code guaranteed to not modify anything but m.

    memset( &m , 0 , sizeof( m ) ) ;

(It occurs to me: I've always supposed that it is, but I haven't
the foggiest notion of where this guarantee is in the standard.
Anybody else?)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient   e objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/03/18
Raw View
Steve Clamage wrote in message <6emr9c$ebu@engnews1.Eng.Sun.COM>...
>I don't think there is any portable way to find the "size" of a type
>that doesn't include such padding

For POD you can find out how much trailing padding to ignore:
   size = offset_of(mystruct, last_member) + sizeof(last_member);

struct X { int i; char c; };

On some platforms I'd expect sizeof(X) to be eight while offsetof(X,c)+1 is
5.
If the last member of your POD is another struct, apply the rule
recursively.  Unlike sizeof(), you've got to know the name of the last
member to make this work.

>and it isn't clear to me that the
>concept has any useful meaning in a portable program.


For serialization (memcpy, dwrite, ...) it might provide some small amount
of compression/optimization.




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/03/19
Raw View
Steve Clamage wrote:
>
> (You can compare or subtract
> addresses of sub-objects of the same object, or of elements of the
> same array. But in those cases, padding will have been supplied,
> and you will get the same answer as sizeof.)

True. The padding has to be supplied even if the object isn't part of an
array:

 struct foo {
     struct bar {
         int x;
         char y;
         } thebar;
     // padding needed here
     char z;
     } thefoo;

in case you do something like

 memset(&thefoo.thebar, 0, sizeof(thefoo.thebar));

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/03/19
Raw View
Martijn Lievaart wrote:
>
> Paul D. DeRocco wrote in message <350E2D55.94A3D80F@ix.netcom.com>...
> >... rounded up to the next alignment boundary, so that arrays will
> >work properly.
> >
>
> Are you sure? I always thought sizeof returned the size of the type,
> which itself may not be what you expect due to padding.
>
> So on a sun, f.i.
>     sizeof(struct { char a[3]; })
> is 3 and
>     sizeof(struct { int i; char c; })
> is 8 and
>     sizeof(struct { char a[3]; short s})
> is 6.

That's exactly my point. We agree.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/03/17
Raw View
Martijn Lievaart wrote:
>
> sizeof is computed at compile time. It computes to the size of the
> type given as argument, not to the object given at runtime.

... rounded up to the next alignment boundary, so that arrays will work
properly.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Martijn Lievaart" <nospam@somewhere.org>
Date: 1998/03/17
Raw View
Paul D. DeRocco wrote in message <350E2D55.94A3D80F@ix.netcom.com>...
>Martijn Lievaart wrote:
>>
>> sizeof is computed at compile time. It computes to the size of the
>> type given as argument, not to the object given at runtime.
>
>... rounded up to the next alignment boundary, so that arrays will work
>properly.
>

Are you sure? I always thought sizeof returned the size of the type, which
itself may not be what you expect due to padding.

So on a sun, f.i.
    sizeof(struct { char a[3]; })
is 3 and
    sizeof(struct { int i; char c; })
is 8 and
    sizeof(struct { char a[3]; short s})
is 6.

These, I think, are the real sizes of these types. The layout of these types
is aligned so they can be used in arrays.
So f.i. the second struct would have the memory structure {first 4 bytes
contain i, 5th contains c, 3 bytes padding}. (Note the padding is part of
the type).
The 3rd struct has a byte of padding between a and s. The 1st struct uses no
padding at all.

This padding is needed so that in arrays of structs, every member of the
struct can be adressed on a alignment boundery appropriate for that member.

Am I wrong?

Greetz,
Martijn
(mlievaar(at)orion(dot)nl)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/03/18
Raw View
In article 1@news2.xs4all.nl, "Martijn Lievaart" <nospam@somewhere.org> writes:
>Paul D. DeRocco wrote in message <350E2D55.94A3D80F@ix.netcom.com>...
>>Martijn Lievaart wrote:
>>>
>>> sizeof is computed at compile time. It computes to the size of the
>>> type given as argument, not to the object given at runtime.
>>
>>... rounded up to the next alignment boundary, so that arrays will work
>>properly.
>>
>
>Are you sure? I always thought sizeof returned the size of the type, which
>itself may not be what you expect due to padding.

The definition of sizeof in both the C and C++ standards includes the
padding needed for arrays. The standards make some implicit assumptions
about alignment and padding. For example, it seems to be assumed that
the alignment boundary for a type does not exceed the size of the type,
and that the alignment needed for a "small" type is no bigger than the
alignment for a "larger" type. These assumptions apply to architectures
I'm familiar with. I don't know whether those implicit assumptions
do cause or could cause problems for unusual architectures.

I don't think there is any portable way to find the "size" of a type
that doesn't include such padding, and it isn't clear to me that the
concept has any useful meaning in a portable program.

For example, you might be tempted to try this:
 void CheckSize()
 {
  MyType m;
  char c; // assume c doesn't get aligned

  if( labs((char*)&m - &c) != sizeof(m) )
   cout << "Gotcha!";
 }
... the idea being that maybe you could detect when sizeof(m) is not
the same as the space actually occupied by a single object.

But comparing or subtracting addresses of unrelated objects has
undefined results, so code like this is not even required to compile,
let alone produce a useful result. (You can compare or subtract
addresses of sub-objects of the same object, or of elements of the
same array. But in those cases, padding will have been supplied,
and you will get the same answer as sizeof.)

In valid and portable code you need to assume that an object really
requires sizeof(object) bytes of storage.

---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Martijn Lievaart" <nospam@somewhere.org>
Date: 1998/03/15
Raw View
Mikael T yr  wrote in message <6eakfj$5hk$1@news1.enator.se>...
>The function sizeof can calculate the size of an object of some type of
>class, but can it handle object's of a class that use inheritance?
>
>Ex. the CBaseClass my contain 2 int and the CSubClass 2 int.
>CBaseClass pBase = new CSubClass();

This will not compile 1), you probably mean:
CBaseClass *pBase = new CSubClass();

>sizeof(pBase)=?

sizeof a pointer to CBaseClass == sizeof datapointer, usually around 4
bytes.

However,
sizeof(*pBase) == sizeof(CBaseClass)

>
>How intelligente is sizeof?

sizeof is computed at compile time. It computes to the size of the type
given as argument, not to the object given at runtime.

1) except when CBaseClass has an operator =(CSub_or_BaseClass *)

Martijn
(mlievaar(at)orion(dot)nl)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]