
At first english is not my primary language and all my books on C++ are in polish so I have to translate. I'm afraid I'm not using correct words or terms but I will try to be as descripting as possible to be understood. I have a question on placement of subobjects in a class (or struct - what I know of standard this will be the same). In S. Lippman's "Inside the C++ Object Model" I found that standard only guaranties that subobjects are placed in specific sequence (not to get inside details) but there is no guarante that compiler doesn't place some additional objects (for his internal use) at the begining of object in between subobjects or at the end. (I looked also in Stroustrup's "The C++ Programming Language" and "The Design and Evolution of C++" but have found nothing - but I wasn't looking that hard). So, if I have a class: class point2d { public: double x; double y; }; and make an object of it point2d pp = new point2d; than ther is no guaranty that reinterpret_cast<double*>(pp) will give me addres of point2d::x. Normally it no difference but if I want to write a class that for example warps comunication with some hardware than I have to be SURE how data would be allocated in memory becouse it must be correct acording to this hardware specification (if hardware keeps in memory a buffer with a char [for command] and int [for argument]) than I my class members must be so placed in this mamory). Another example is color. If I want to write a class that warps color managemant I want it to be more useable I have to be sure that class class color_argb { public: unsigned char a; unsigned char r; unsigned char g; unsigned char b; }; will use ONLY 4 chars (bytes) and ther will not be any other data placed in memory. If one would be added (for example virtual table pointer) than color_argb could not be used to warp data recevied from and given to many libraries and hardware. I suppose that if I don't use any polimorphism (as virtual functions), inherit only in single line and without virtual base classes and don't use any runtime support that compiler doesn't have any reason to place additional data (but still can use more than 4 bytes to align data for example). But what I know it still MAY do this and relaying on that that it does not have to is dangarous. So how is it? Thanks in advance. Adam Badura

A struct with no methods should, I believe, have a straightforward memory mapping in order to be backwards-compatible with C. In order to provide a struct-like interface to a class without losing the benefits of data hiding by declaring its members as public, I like to use a nested struct, like so: class point2d { public: struct data { double x, y; }; point2d( data const& Data ): Data_(Data) {;} operator data( void ) const { return Data_; } point2d( double X, double Y ): { Data_.x= X; Data_.y= Y; } double X( void ) const { return Data_.x; } double setX( double Value ) { Data_.x= Value; } double Y( void ) const { return Data_.y; } void setY( double Value ) { Data_.y= Value; } private: data Data_; }; The non-explicit constructor taking an instance of the nested struct as argument and a conversion method to the nested struct type provides seamless interoperability between instances of the class and its nested struct like so: point2d::data Data; Data.x= 6.0; Data.y= 8.0; point2d Point2D= Data; Point2d.setX(Point2d.X() * Point2d.Y()); Point2d.setY(0.0) point2d::data Data= Point2D; When you want a full-blown object interface to the data, use the class, when you want a struct-like interface to the data, use the nested struct instead. Adam Badura wrote:
At first english is not my primary language and all my books on C++ are in polish so I have to translate. I'm afraid I'm not using correct words or terms but I will try to be as descripting as possible to be understood.
I have a question on placement of subobjects in a class (or struct - what I know of standard this will be the same). In S. Lippman's "Inside the C++ Object Model" I found that standard only guaranties that subobjects are placed in specific sequence (not to get inside details) but there is no guarante that compiler doesn't place some additional objects (for his internal use) at the begining of object in between subobjects or at the end. (I looked also in Stroustrup's "The C++ Programming Language" and "The Design and Evolution of C++" but have found nothing - but I wasn't looking that hard).
So, if I have a class:
class point2d { public: double x; double y; };
and make an object of it
point2d pp = new point2d;
than ther is no guaranty that
reinterpret_cast<double*>(pp) will give me addres of point2d::x.
Normally it no difference but if I want to write a class that for example warps comunication with some hardware than I have to be SURE how data would be allocated in memory becouse it must be correct acording to this hardware specification (if hardware keeps in memory a buffer with a char [for command] and int [for argument]) than I my class members must be so placed in this mamory). Another example is color. If I want to write a class that warps color managemant I want it to be more useable I have to be sure that class
class color_argb { public: unsigned char a; unsigned char r; unsigned char g; unsigned char b; };
will use ONLY 4 chars (bytes) and ther will not be any other data placed in memory. If one would be added (for example virtual table pointer) than color_argb could not be used to warp data recevied from and given to many libraries and hardware.
I suppose that if I don't use any polimorphism (as virtual functions), inherit only in single line and without virtual base classes and don't use any runtime support that compiler doesn't have any reason to place additional data (but still can use more than 4 bytes to align data for example). But what I know it still MAY do this and relaying on that that it does not have to is dangarous. So how is it?
Thanks in advance.
Adam Badura
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Adam Badura wrote:
At first english is not my primary language and all my books on C++ are in polish so I have to translate. I'm afraid I'm not using correct words or terms but I will try to be as descripting as possible to be understood.
I have a question on placement of subobjects in a class (or struct - what I know of standard this will be the same). In S. Lippman's "Inside the C++ Object Model" I found that standard only guaranties that subobjects are placed in specific sequence (not to get inside details) but there is no guarante that compiler doesn't place some additional objects (for his internal use) at the begining of object in between subobjects or at the end. (I looked also in Stroustrup's "The C++ Programming Language" and "The Design and Evolution of C++" but have found nothing - but I wasn't looking that hard).
So, if I have a class:
class point2d { public: double x; double y; };
and make an object of it
point2d pp = new point2d;
point2d * pp = new point2d;
than ther is no guaranty that
reinterpret_cast<double*>(pp) will give me addres of point2d::x.
Correct. But many compilers allow you to specify a packing which can ensure that your expression will work as specified. That is compiler specific but nor part of the C++ standard.

On 09/17/2005 10:55 AM, Adam Badura wrote: [snip]
I have a question on placement of subobjects in a class (or struct - what I know of standard this will be the same). In S. Lippman's "Inside the C++ Object Model" I found that standard only guaranties that subobjects are placed in specific sequence (not to get inside details) but there is no guarante that compiler doesn't place some additional objects (for his internal use) at the begining of object in between subobjects or at the end. (I looked also in Stroustrup's "The C++ Programming Language" and "The Design and Evolution of C++" but have found nothing - but I wasn't looking that hard).
So, if I have a class:
class point2d { public: double x; double y; };
and make an object of it
point2d pp = new point2d;
than ther is no guaranty that
reinterpret_cast<double*>(pp) will give me addres of point2d::x.
Normally it no difference but if I want to write a class that for example warps comunication with some hardware than I have to be SURE how data would be allocated in memory becouse it must be correct acording to this hardware specification (if hardware keeps in memory a buffer with a char [for command] and int [for argument]) than I my class members must be so placed in this mamory). Another example is color. If I want to write a class that warps color managemant I want it to be more useable I have to be sure that class
class color_argb { public: unsigned char a; unsigned char r; unsigned char g; unsigned char b; };
will use ONLY 4 chars (bytes) and ther will not be any other data placed in memory. If one would be added (for example virtual table pointer) than color_argb could not be used to warp data recevied from and given to many libraries and hardware.
I suppose that if I don't use any polimorphism (as virtual functions), inherit only in single line and without virtual base classes and don't use any runtime support that compiler doesn't have any reason to place additional data (but still can use more than 4 bytes to align data for example). But what I know it still MAY do this and relaying on that that it does not have to is dangarous. So how is it?
You could specify the actual layout, as done here: http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/indexed_types/composite_product.hpp?rev=1.1&view=auto however, this would require you to define an enumeration for each class. For example for the point2d, there would be: enum point2d_fields { x , y }; and then, instead of your point2d struct, there would be a composite_product with member function: project<x> Please see the tests at: http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/libs/indexed_types/test/composite_product_test.cpp?rev=1.1&view=auto for clarification. As shown in composite_product.hpp, the memory is explicitly laid out by the factor template; hence, you know exactly where each subobject is located. I've worked on a type of policy_composite allowing different methods for constructing the composite, amoung other features. However, so far, it hasn't prompted much interest:

"Adam Badura" <abadura@o2.pl> writes:
At first english is not my primary language and all my books on C++ are in polish so I have to translate. I'm afraid I'm not using correct words or terms but I will try to be as descripting as possible to be understood.
I have a question on placement of subobjects in a class (or struct - what I know of standard this will be the same). In S. Lippman's "Inside the C++ Object Model" I found that standard only guaranties that subobjects are placed in specific sequence (not to get inside details) but there is no guarante that compiler doesn't place some additional objects (for his internal use) at the begining of object in between subobjects or at the end. (I looked also in Stroustrup's "The C++ Programming Language" and "The Design and Evolution of C++" but have found nothing - but I wasn't looking that hard).p
This post isn't really related to libraries or Boost. Please take the thread to an appropriate forum, like comp.std.c++ for example. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (5)
-
Adam Badura
-
David Abrahams
-
Edward Diener
-
Jason Kankiewicz
-
Larry Evans