Connecting Tech Pros Worldwide Help | Site Map

is this class POD ?

bartek
Guest
 
Posts: n/a
#1: Jul 22 '05
template <class T, unsigned size>
struct Array {
typedef unsigned SizeType;
typedef T ValueType;
typedef T* Ptr;
typedef T const* ConstPtr;

// Default copy ctor and assignment op are fine.

SizeType Size() const { return size; }

T& operator[](SizeType i) { return m_array[i]; }
T const& operator[](SizeType i) const { return m_array[i]; }

Ptr Begin() { return &m_array[0]; }
ConstPtr Begin() const { return &m_array[0]; }

Ptr End() { return &m_array[0] + size; }
ConstPtr End() const { return &m_array[0] + size; }

private:
ValueType m_array[size];
};

It defines neither a copy-ctor nor a destructor.
Does the presence of private section render it as non-POD?

I assume that, if the above class was a POD type, objects of the
following types T and U would end up with equivalent memory layout:

typedef float TX[3];
typedef TX TY[4];

typedef Array<float, 3> UX;
typedef Array<UX, 4> UY;

typedef TY T;
typedef UY U;

Thanks.
--
:: bartekd [at] o2 [dot] pl

Rob Williscroft
Guest
 
Posts: n/a
#2: Jul 22 '05

re: is this class POD ?


bartek wrote in news:Xns94E29F6CD4C24bartekdqwertyuiopo2p@153.19.2 51.200 in
comp.lang.c++:

Subject: is this class POD ?
[color=blue]
> template <class T, unsigned size>
> struct Array {[/color]

[snip POD-ish stuff]
[color=blue]
>
> private:
> ValueType m_array[size];
> };
>
> It defines neither a copy-ctor nor a destructor.
> Does the presence of private section render it as non-POD?
>[/color]

The private section isn't the problem, its the private *data*.
[color=blue]
> I assume that, if the above class was a POD type, objects of the
> following types T and U would end up with equivalent memory layout:
>
> typedef float TX[3];
> typedef TX TY[4];
>
> typedef Array<float, 3> UX;
> typedef Array<UX, 4> UY;
>
> typedef TY T;
> typedef UY U;
>[/color]

I don't really understand the above, but it doesn't matter
as Array<> isn't a POD.

Unfortunatly POD only really exists as a concept to provide
compatibility with how C ( no ++ ) does things, useful uses
beyond that are rare.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
bartek
Guest
 
Posts: n/a
#3: Jul 22 '05

re: is this class POD ?


Rob Williscroft <rtw@freenet.co.uk> wrote in
news:Xns94E2966E1E75FukcoREMOVEfreenetrtw@130.133. 1.4:
[color=blue]
> bartek wrote in
> news:Xns94E29F6CD4C24bartekdqwertyuiopo2p@153.19.2 51.200 in
> comp.lang.c++:
>
> Subject: is this class POD ?
>[color=green]
>> template <class T, unsigned size>
>> struct Array {[/color]
>
> [snip POD-ish stuff]
>[color=green]
>>
>> private:
>> ValueType m_array[size];
>> };
>>
>> It defines neither a copy-ctor nor a destructor.
>> Does the presence of private section render it as non-POD?
>>[/color]
>
> The private section isn't the problem, its the private *data*.[/color]

That's what I actually meant.
In that case, making the data public would result in the Array class
becoming POD-compliant?
[color=blue][color=green]
>> I assume that, if the above class was a POD type, objects of the
>> following types T and U would end up with equivalent memory layout:
>>
>> typedef float TX[3];
>> typedef TX TY[4];
>>
>> typedef Array<float, 3> UX;
>> typedef Array<UX, 4> UY;
>>
>> typedef TY T;
>> typedef UY U;
>>[/color]
>
> I don't really understand the above, but it doesn't matter
> as Array<> isn't a POD.
>
> Unfortunatly POD only really exists as a concept to provide
> compatibility with how C ( no ++ ) does things, useful uses
> beyond that are rare.[/color]

Sorry for putting it in a somewhat contrived way.
Indeed C compatibility is what I'm going after.

Say, I have a C library which uses similar typedefs around in its
interfaces:

typedef float my_vector_t[3];
typedef float my_matrix_t[4][4];

I need to use those interfaces from C++ code.
Though, I'd like to keep out from using C arrays in my interfaces, so
wrapping arrays into a class seems a reasonable solution. Moreover, if
those C++ wrapped arrays were binary-compatible with C arrays, I could
gain both performance and unification.

If I was sure that the following C++ objects and C arrays had equivalent
binary representations, I could get rid of explicit conversions on
interface borders, and get the adventage of using strict types throughout
my program.

float x[4][4];
Array<Array<float, 4>, 4> y;

--
:: bartekd [at] o2 [dot] pl

Rob Williscroft
Guest
 
Posts: n/a
#4: Jul 22 '05

re: is this class POD ?


bartek wrote in news:Xns94E2A41A0B1A4bartekdqwertyuiopo2p@153.19.2 51.200
in comp.lang.c++:
[color=blue][color=green]
>> The private section isn't the problem, its the private *data*.[/color]
>
> That's what I actually meant.
> In that case, making the data public would result in the Array class
> becoming POD-compliant?[/color]

Yes.
[color=blue]
>[/color]

[snip]
[color=blue][color=green]
>>
>> Unfortunatly POD only really exists as a concept to provide
>> compatibility with how C ( no ++ ) does things, useful uses
>> beyond that are rare.[/color]
>
> Sorry for putting it in a somewhat contrived way.
> Indeed C compatibility is what I'm going after.
>
> Say, I have a C library which uses similar typedefs around in its
> interfaces:
>
> typedef float my_vector_t[3];
> typedef float my_matrix_t[4][4];
>
> I need to use those interfaces from C++ code.
> Though, I'd like to keep out from using C arrays in my interfaces, so
> wrapping arrays into a class seems a reasonable solution. Moreover, if
> those C++ wrapped arrays were binary-compatible with C arrays, I could
> gain both performance and unification.
>
> If I was sure that the following C++ objects and C arrays had
> equivalent binary representations, I could get rid of explicit
> conversions on interface borders, and get the adventage of using
> strict types throughout my program.
>
> float x[4][4];
> Array<Array<float, 4>, 4> y;[/color]

eg

struct xplusplus
{
float x[4][4];
// whatever ...
};

IIU( The Standard )C, x is at offset 0 of xplusplus, but you may
be able to find a platform where sizeof( xplusplus ) > sizeof( x ).

So maybe:

Array<Array<float, 4>, 4> &y = *
reinterpret_cast< Array<Array<float, 4>, 4> * >( x )
;

Will work Ok until you try copying your Array.

Don't do it its UB. If you get your code working, your tying
your code to your current platform and your current compiler.

If you show some samples of the C API your dealing with then
myself or others may be able to give some better advice on
how best to deal with it.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
John Carson
Guest
 
Posts: n/a
#5: Jul 22 '05

re: is this class POD ?


"bartek" <spam.will.eat.itself@o2.pl> wrote in message
news:Xns94E29F6CD4C24bartekdqwertyuiopo2p@153.19.2 51.200[color=blue]
> template <class T, unsigned size>
> struct Array {
> typedef unsigned SizeType;
> typedef T ValueType;
> typedef T* Ptr;
> typedef T const* ConstPtr;
>
> // Default copy ctor and assignment op are fine.
>
> SizeType Size() const { return size; }
>
> T& operator[](SizeType i) { return m_array[i]; }
> T const& operator[](SizeType i) const { return m_array[i]; }
>
> Ptr Begin() { return &m_array[0]; }
> ConstPtr Begin() const { return &m_array[0]; }
>
> Ptr End() { return &m_array[0] + size; }
> ConstPtr End() const { return &m_array[0] + size; }
>
> private:
> ValueType m_array[size];
> };
>
> It defines neither a copy-ctor nor a destructor.
> Does the presence of private section render it as non-POD?
>
> I assume that, if the above class was a POD type, objects of the
> following types T and U would end up with equivalent memory layout:
>
> typedef float TX[3];
> typedef TX TY[4];
>
> typedef Array<float, 3> UX;
> typedef Array<UX, 4> UY;
>
> typedef TY T;
> typedef UY U;
>
> Thanks.
> --[color=green][color=darkred]
>>> bartekd [at] o2 [dot] pl[/color][/color][/color]


http://www.parashift.com/c++-faq-lit....html#faq-26.7


--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)
bartek
Guest
 
Posts: n/a
#6: Jul 22 '05

re: is this class POD ?


Rob Williscroft <rtw@freenet.co.uk> wrote in
news:Xns94E2A56B8AE74ukcoREMOVEfreenetrtw@130.133. 1.4:

(...)
[color=blue]
> eg
>
> struct xplusplus
> {
> float x[4][4];
> // whatever ...
> };
>
> IIU( The Standard )C, x is at offset 0 of xplusplus, but you may
> be able to find a platform where sizeof( xplusplus ) > sizeof( x ).[/color]

Of course, it seems I was missing the obvious all the time.

Somehow, I assumed that:

struct X {
float x;
};

being a POD, should be equivalent to:

float x;

Obviously, I was missing the point. POD-ness is not relevant here.
Thanks for pointing that out.

--
:: bartekd [at] o2 [dot] pl

Claudio Puviani
Guest
 
Posts: n/a
#7: Jul 22 '05

re: is this class POD ?


"bartek" <spam.will.eat.itself@o2.pl> wrote[color=blue]
> template <class T, unsigned size>
> struct Array {
> typedef unsigned SizeType;
> typedef T ValueType;
> typedef T* Ptr;
> typedef T const* ConstPtr;
>
> // Default copy ctor and assignment op are fine.
>
> SizeType Size() const { return size; }
>
> T& operator[](SizeType i) { return m_array[i]; }
> T const& operator[](SizeType i) const { return m_array[i]; }
>
> Ptr Begin() { return &m_array[0]; }
> ConstPtr Begin() const { return &m_array[0]; }
>
> Ptr End() { return &m_array[0] + size; }
> ConstPtr End() const { return &m_array[0] + size; }
>
> private:
> ValueType m_array[size];
> };[/color]

Because this is a template, whether or not an instantiation is a POD type depends
on the template arguments. An Array<double, 5> would be a POD type, but an
Array<std::string, 7> would not because std::string itself is not a POD. The
presence of typedefs and non-virtual member functions doesn't make a class a
non-POD type.
[color=blue]
> It defines neither a copy-ctor nor a destructor.[/color]

That's irrelevant to determining whether a class is a POD type.
[color=blue]
> Does the presence of private section render it as non-POD?[/color]

No. POD types are allowed to have private sections.

It's a loose convention to make POD types structs (of PODs) with only data
members, but it's not a technical limitation. A class with only POD data members
and with only non-virtual member functions is itself a POD, regardless of how you
set up accessibility. To be even more evil, a class could have non-POD _static_
data members and still be a POD type. :-)

Claudio Puviani



bartek
Guest
 
Posts: n/a
#8: Jul 22 '05

re: is this class POD ?


"Claudio Puviani" <puviani@hotmail.com> wrote in
news:wk0nc.164606$Gd3.45000232@news4.srv.hcvlny.cv .net:
[color=blue]
> "bartek" <spam.will.eat.itself@o2.pl> wrote[color=green]
>> template <class T, unsigned size>
>> struct Array {
>> typedef unsigned SizeType;
>> typedef T ValueType;
>> typedef T* Ptr;
>> typedef T const* ConstPtr;
>>
>> // Default copy ctor and assignment op are fine.
>>
>> SizeType Size() const { return size; }
>>
>> T& operator[](SizeType i) { return m_array[i]; }
>> T const& operator[](SizeType i) const { return m_array[i]; }
>>
>> Ptr Begin() { return &m_array[0]; }
>> ConstPtr Begin() const { return &m_array[0]; }
>>
>> Ptr End() { return &m_array[0] + size; }
>> ConstPtr End() const { return &m_array[0] + size; }
>>
>> private:
>> ValueType m_array[size];
>> };[/color]
>
> Because this is a template, whether or not an instantiation is a POD
> type depends on the template arguments. An Array<double, 5> would be a
> POD type, but an Array<std::string, 7> would not because std::string
> itself is not a POD. The presence of typedefs and non-virtual member
> functions doesn't make a class a non-POD type.[/color]

Yes of course you're right. I somehow didn't mention the 'background'
information regarding the class. Indeed, regarding POD-ness, I meant it
only for primitive types.
[color=blue][color=green]
>> It defines neither a copy-ctor nor a destructor.[/color]
>
> That's irrelevant to determining whether a class is a POD type.
>[color=green]
>> Does the presence of private section render it as non-POD?[/color]
>
> No. POD types are allowed to have private sections.
>
> It's a loose convention to make POD types structs (of PODs) with only
> data members, but it's not a technical limitation. A class with only
> POD data members and with only non-virtual member functions is itself
> a POD, regardless of how you set up accessibility. To be even more
> evil, a class could have non-POD _static_ data members and still be a
> POD type. :-)[/color]

Soon after posting the question, I've realised that I misinterpreted the
definition of POD.

While POD reserves binary compatibility with C structs, I have confused
it with some sort of "encapsulated-type equivalence"... That is, I
thought that a class (no bases, no virtuals, no non-trivial copy or
destruction) with a single data member of type T, is guaranteed to have
the same memory layout as the type T by itself.

I've assumed that:

struct X {
float f[3];
};

has the same binary representation as:

typedef float Y[3];

so that:

X array_of_x[10];

ends up with the same memory layout as:

Y array_of_y[10];

Now I realise that, though, it seems to work on many platforms,
of course, it is not guaranteed.

Cheers.
--
:: bartekd [at] o2 [dot] pl

Rob Williscroft
Guest
 
Posts: n/a
#9: Jul 22 '05

re: is this class POD ?


Claudio Puviani wrote in news:wk0nc.164606$Gd3.45000232
@news4.srv.hcvlny.cv.net in comp.lang.c++:
[color=blue]
>[color=green]
>> It defines neither a copy-ctor nor a destructor.[/color]
>
> That's irrelevant to determining whether a class is a POD type.
>
>[/color]

From 9/4:

A POD-struct is an aggregate class that has no non-static data
members of type non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-defined copy assignment
operator and no user-defined destructor.

"aggregate class" (8.5.1) may not have user defined ctor's, so any
ctor/dtor is right out.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Claudio Puviani
Guest
 
Posts: n/a
#10: Jul 22 '05

re: is this class POD ?


"Rob Williscroft" <rtw@freenet.co.uk> wrote[color=blue]
> Claudio Puviani wrote[color=green]
> >[color=darkred]
> >> It defines neither a copy-ctor nor a destructor.[/color]
> >
> > That's irrelevant to determining whether a class is a POD type.
> >
> >[/color]
>
> From 9/4:
>
> A POD-struct is an aggregate class that has no non-static data
> members of type non-POD-struct, non-POD-union (or array of such
> types) or reference, and has no user-defined copy assignment
> operator and no user-defined destructor.
>
> "aggregate class" (8.5.1) may not have user defined ctor's, so any
> ctor/dtor is right out.[/color]

Thank you. If I'd taken a moment to think about it, it should have been obvious
to me even without checking the standard, since a memcopy or memset would violate
any contraints imposed by those two functions.

Claudio Puviani


John Carson
Guest
 
Posts: n/a
#11: Jul 22 '05

re: is this class POD ?


"Claudio Puviani" <puviani@hotmail.com> wrote in message
news:wk0nc.164606$Gd3.45000232@news4.srv.hcvlny.cv .net[color=blue]
> A class with only
> POD data members and with only non-virtual member functions is itself
> a POD, regardless of how you set up accessibility. To be even more
> evil, a class could have non-POD _static_ data members and still be a
> POD type. :-)[/color]


Further to Rob's point, 8.5.1 p1 reads:

An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members (clause
11), no base classes (clause 10), and no virtual functions (10.3).


Thus non-static private (and protected) members are ruled out.

--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)

Claudio Puviani
Guest
 
Posts: n/a
#12: Jul 22 '05

re: is this class POD ?


"John Carson" <donaldquixote@datafast.net.au> wrote[color=blue]
> "Claudio Puviani" <puviani@hotmail.com> wrote[color=green]
> > A class with only
> > POD data members and with only non-virtual member functions is itself
> > a POD, regardless of how you set up accessibility. To be even more
> > evil, a class could have non-POD _static_ data members and still be a
> > POD type. :-)[/color]
>
>
> Further to Rob's point, 8.5.1 p1 reads:
>
> An aggregate is an array or a class (clause 9) with no user-declared
> constructors (12.1), no private or protected non-static data members (clause
> 11), no base classes (clause 10), and no virtual functions (10.3).
>
>
> Thus non-static private (and protected) members are ruled out.[/color]

Again one of those things that 30 more seconds of thought would have brought up.
Since compilers are allowed to reorder data members that have different
accessibility, obviously (in retrospect), classes with mixed access specifiers
can't be POD types.

Interestingly, since a class that has all data members either private or
protected shares the same physical attributes as one that has only public data
members, we can infer that an implicit requirement for a POD is that it must
allow static initializers like:

XYZ xyz = { 1, 'b', 2.7 };

I'm not sure that this limitation is particularly meanigful or useful, but then
again, it doesn't even rank as high as a minor irritant.

Thanks for pointing out clause 11. I need to stop posting at 4am. ;-)

Claudio Puviani


Jerry Coffin
Guest
 
Posts: n/a
#13: Jul 22 '05

re: is this class POD ?


"Claudio Puviani" <puviani@hotmail.com> wrote in message news:<uxhnc.173639$Gd3.48297236@news4.srv.hcvlny.c v.net>...

[ ... ]
[color=blue]
> Since compilers are allowed to reorder data members that have different
> accessibility, obviously (in retrospect), classes with mixed access specifiers
> can't be POD types.[/color]

Technically, they can be, but they don't provide the guarantees that
people normally associate with POD types. The wording of the standard
also has one other little oddity in this area: even a vacuous access
specifier has the same effect. Consider, the following:

struct X {
int x;
public: int y;
public: int z;
};

This still fits the standard's definition of POD but the relative
order of y and z is not guaranteed, even though neither "public:" has
changed accessibility of anything.

This problem should probably be forwarded to the standards committee,
but I've had a few too many bouts with censorship on
comp.lang.c++.moderated and comp.std.c++, so the dubious honor of
doing so will have to fall to somebody else.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Closed Thread