C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Reading objects from an array of char
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
glenlow@pixelglow.com
Guest





PostPosted: Tue Dec 14, 2004 8:33 pm    Post subject: Reading objects from an array of char Reply with quote



Hi All,

Consider the following:

T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;
T t2 = *reinterpret_cast <T*> (buffer);

I don't think the last statement is kosher with respect to the aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored object
type really a T?

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ali Çehreli
Guest





PostPosted: Wed Dec 15, 2004 1:38 am    Post subject: Re: Reading objects from an array of char Reply with quote



<glenlow (AT) pixelglow (DOT) com> wrote


Quote:
T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;

Undefined behavior above. You are calling operator= on an unitialized
piece of memory. buffer does not contain a T because no constructor has
constructed a T on that memory.

I think you should use placement new to construct the object on
buffer.

Quote:
T t2 = *reinterpret_cast <T*> (buffer);

That's fine only if buffer contains a valid T; and that's not the case
with the code posted.

Quote:
I don't think the last statement is kosher with respect to the aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored object
type really a T?

Do you mean alignment issues; as in, probably a T could not have been
placed on buffer?

Though my gut feeling is that it should be ok (judging from how
container classes like std::vector work with any type), I need a
definitive answer as well.

Ali


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jack Klein
Guest





PostPosted: Wed Dec 15, 2004 4:39 am    Post subject: Re: Reading objects from an array of char Reply with quote



On 14 Dec 2004 15:33:02 -0500, [email]glenlow (AT) pixelglow (DOT) com[/email] wrote in
comp.lang.c++.moderated:

Quote:
Hi All,

Consider the following:

T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;
T t2 = *reinterpret_cast <T*> (buffer);

I don't think the last statement is kosher with respect to the aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored object
type really a T?

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com

Depends on two things. First what T is, if it has a non-trivial
constructor or a user-defined assignment operator, there's a good
chance it will fail. Second is alignment. Say T is, for example, a
double, on an implementation where sizeof(double) is 8 and doubles
must be located at addresses evenly divisible by 8. If 'buffer' does
not have the correct alignment for T, undefined behavior occurs.

Placement new could take care of the first, if the object requires
construction to be valid, but not the second.

In C++, as in C, memory is memory is memory. What counts is not
really the object type, but the type of lvalue used. The block of
memory (which is what an object is) has no type, values stored in
memory have types imposed by the type of the lvalue used to store them
there.

If you have a pointer to a large enough array of characters that is
suitably aligned, you may copy a POD object to it or construct any
sort of object in it. At that point is may no longer be legitimate to
access it as an array of signed characters, but it is valid to access
via an lvalue of the type of the actual value it contains.

There is no difference between an ordinary array of characters and a
block of bytes allocated with malloc() of the same size, other than a
possible alignment issue.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
glenlow@pixelglow.com
Guest





PostPosted: Wed Dec 15, 2004 4:42 am    Post subject: Re: Reading objects from an array of char Reply with quote

Quote:
T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;

Undefined behavior above. You are calling operator= on an unitialized
piece of memory. buffer does not contain a T because no constructor
has
constructed a T on that memory.

I think you should use placement new to construct the object on
buffer.

Apologies, you're right, it should be:

new (buffer) (t);

Quote:
I don't think the last statement is kosher with respect to the
aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored
object
type really a T?

Do you mean alignment issues; as in, probably a T could not have been
placed on buffer?

Now that you mention it, alignment would probably defeat this,
irrespective of whether aliasing would work. I know malloc and new are
supposed to yield memory suitable for any type to put in,
alignment-wise. Does a simple (auto) char buffer have this guarantee?

The aliasing issue is also problematic. The C99 standard (and probably
the C++ standard if you interpret it compatibly) seems to think that
(heap?) allocated memory "becomes" the first type you put in e.g. by
memcpy or assignment. On the other hand, auto memory with a declared
type is that declared type, so reading another type from it might
violate the aliasing rules.
Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Wed Dec 15, 2004 4:47 am    Post subject: Re: Reading objects from an array of char Reply with quote

[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:
Quote:
Hi All,

Consider the following:

T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;
T t2 = *reinterpret_cast <T*> (buffer);

I don't think the last statement is kosher with respect to the aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored object
type really a T?

According to standard section 3.8 paragraphs 1-2, buffer contains an
object of every POD type for which it is suitably aligned and sized
(but obviously not a valid object!). Assuming you restrict T to be a
POD type and ensure correct alignment of buffer, then the stored
object type is indeed a T.

--
Ben Hutchings
compatible: Gracefully accepts erroneous data from any source

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Wed Dec 15, 2004 4:47 pm    Post subject: Re: Reading objects from an array of char Reply with quote


<glenlow (AT) pixelglow (DOT) com> schrieb im Newsbeitrag
news:1103075881.288182.281390 (AT) z14g2000cwz (DOT) googlegroups.com...
Quote:
T t;
char buffer [sizeof (T)];
*reinterpret_cast <T*> (buffer) = t;

Undefined behavior above. You are calling operator= on an unitialized
piece of memory. buffer does not contain a T because no constructor
has
constructed a T on that memory.

I think you should use placement new to construct the object on
buffer.

Apologies, you're right, it should be:

new (buffer) (t);

I don't think the last statement is kosher with respect to the
aliasing
rules since the declared object type is char [N] and not T; on the
other hand, I never write in chars, only T's, so is the stored
object
type really a T?

Do you mean alignment issues; as in, probably a T could not have been
placed on buffer?

Now that you mention it, alignment would probably defeat this,
irrespective of whether aliasing would work. I know malloc and new are
supposed to yield memory suitable for any type to put in,
alignment-wise. Does a simple (auto) char buffer have this guarantee?

No.
Boost has something that finds out alignment, but I think it is only
"guessing", at least for some platforms....

Thomas



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Dec 15, 2004 6:19 pm    Post subject: Re: Reading objects from an array of char Reply with quote

[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:

Quote:
Now that you mention it, alignment would probably defeat this,

Alignement definitly defeats it.

Quote:
irrespective of whether aliasing would work. I know malloc and new
are
supposed to yield memory suitable for any type to put in,
alignment-wise. Does a simple (auto) char buffer have this guarantee?

Not at all. In fact, all of the compilers I use will allocate a char[]
at the first address which happens to be free, regardless of alignment.

Quote:
The aliasing issue is also problematic. The C99 standard (and
probably
the C++ standard if you interpret it compatibly) seems to think that
(heap?) allocated memory "becomes" the first type you put in e.g. by
memcpy or assignment. On the other hand, auto memory with a declared
type is that declared type, so reading another type from it might
violate the aliasing rules.

You can get away with a lot in char[] buffers, provided you have
adequat alignment. The problem is with declared types: if you declare
a
T as a local variable, the destructor for T will be called when the
variable leaves scope. If you get funny and start doing things like
var.~T(), you're likely to have problems when the destructor gets
called.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Branimir Maksimovic
Guest





PostPosted: Thu Dec 16, 2004 1:38 pm    Post subject: Re: Reading objects from an array of char Reply with quote

[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:
Quote:
T t;
char buffer [sizeof (T)];
new (buffer) (t);

Now that you mention it, alignment would probably defeat this,
irrespective of whether aliasing would work. I know malloc and new
are
supposed to yield memory suitable for any type to put in,
alignment-wise. Does a simple (auto) char buffer have this guarantee?

Nope. char buffers have alignment requirement of single char,
and that is weakiest alignment requirement possible.
If you have alloca function available, just use that instead
of char buffer, it guarantees alignment for any type as malloc
does. alloca can be implemented as single assembly
instruction that adjusts stack pointer which means: it never returns
NULL ,
and func(alloca()) is no no.
That's why usage of alloca should be very very restrictive, but
replacing
auto char buffers with it, in order to use allocated memory as storage
for any
type is meaningfull and valid purpose.


Quote:

The aliasing issue is also problematic. The C99 standard (and
probably
the C++ standard if you interpret it compatibly) seems to think that
(heap?) allocated memory "becomes" the first type you put in e.g. by
memcpy or assignment. On the other hand, auto memory with a declared
type is that declared type, so reading another type from it might
violate the aliasing rules.
With mentioned function your concern disappears.


Greetings, Bane.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
glenlow@pixelglow.com
Guest





PostPosted: Fri Dec 17, 2004 11:15 am    Post subject: Re: Reading objects from an array of char Reply with quote

I know of alloca and while it helps with the specific code I submitted,
it won't help with the general case of allocating char buffers e.g.
embedded within an object.
Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Branimir Maksimovic
Guest





PostPosted: Fri Dec 17, 2004 5:31 pm    Post subject: Re: Reading objects from an array of char Reply with quote


[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:
Quote:
I know of alloca and while it helps with the specific code I
submitted,
it won't help with the general case of allocating char buffers e.g.
embedded within an object.

Oh, I see, then use union

eg:

struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

Greetings, Bane.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Dec 21, 2004 12:57 am    Post subject: Re: Reading objects from an array of char Reply with quote

Branimir Maksimovic wrote:
Quote:
glenlow (AT) pixelglow (DOT) com wrote:
I know of alloca and while it helps with the specific code I
submitted, it won't help with the general case of allocating char
buffers e.g. embedded within an object.

Oh, I see, then use union

eg:

struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

And how do you define max_allignment_req_t? I currently use a union of
five or six different types, but there's nothing in the standard which
guarantees it (although I've yet to have it fail in practice).

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Branimir Maksimovic
Guest





PostPosted: Wed Dec 22, 2004 2:52 am    Post subject: Re: Reading objects from an array of char Reply with quote


[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
Branimir Maksimovic wrote:
[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:
I know of alloca and while it helps with the specific code I
submitted, it won't help with the general case of allocating char
buffers e.g. embedded within an object.

Oh, I see, then use union

eg:

struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

And how do you define max_allignment_req_t?

From case to case. Usually it's enough to be size_t
or long, but for vector types (eg SSE 128 bit types on intel) it is

compiler and system specific thing, therefore typedef.

I currently use a union of
Quote:
five or six different types, but there's nothing in the standard
which
guarantees it (although I've yet to have it fail in practice).

It never fails, (although I should say "never say never"Smile).
Greetings, Bane.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Allan W
Guest





PostPosted: Wed Dec 22, 2004 8:57 am    Post subject: Re: Reading objects from an array of char Reply with quote

Quote:
Branimir Maksimovic wrote:
struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
And how do you define max_allignment_req_t? I currently use a union
of
five or six different types, but there's nothing in the standard
which
guarantees it (although I've yet to have it fail in practice).

Through the documentation for the platform (or trial & error, if all
else fails), find the one type with the strictest alignment
requirements. Put it with the other platform-specific code to make
it easier to deal with when porting to other platforms...

// platform_specific.h
#ifndef PLATFORM_SPECIFIC_H
#define PLATFORM_SPECIFIC_H

#if defined(PLATFORM1)
// Only for Platform 1
typedef double max_alignment_req_t;
#elif defined(PLATFORM2)
// Only for Platform 2
typedef long long max_alignment_req_t;
// ... etc
#endif

#endif // PLATFORM_SPECIFIC_H


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Allan W
Guest





PostPosted: Wed Dec 22, 2004 8:58 am    Post subject: Re: Reading objects from an array of char Reply with quote

Quote:
Branimir Maksimovic wrote:
struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
And how do you define max_allignment_req_t? I currently use a union
of
five or six different types, but there's nothing in the standard
which
guarantees it (although I've yet to have it fail in practice).

Through the documentation for the platform (or trial & error, if all
else fails), find the one type with the strictest alignment
requirements. Put it with the other platform-specific code to make
it easier to deal with when porting to other platforms...

// platform_specific.h
#ifndef PLATFORM_SPECIFIC_H
#define PLATFORM_SPECIFIC_H

#if defined(PLATFORM1)
// Only for Platform 1
typedef double max_alignment_req_t;
#elif defined(PLATFORM2)
// Only for Platform 2
typedef long long max_alignment_req_t;
// ... etc
#endif

#endif // PLATFORM_SPECIFIC_H


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Dec 23, 2004 9:42 pm    Post subject: Re: Reading objects from an array of char Reply with quote

Branimir Maksimovic wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:
Branimir Maksimovic wrote:
[email]glenlow (AT) pixelglow (DOT) com[/email] wrote:
I know of alloca and while it helps with the specific code I
submitted, it won't help with the general case of allocating
char buffers e.g. embedded within an object.

Oh, I see, then use union

eg:

struct{
union{ max_allignment_req_t allignment; char buf[42];};
int a;
};

And how do you define max_allignment_req_t?

From case to case. Usually it's enough to be size_t or long,

Except on a Sparc in 32 bit mode. Or most other 32 bit RISC
architectures, I think -- very often, size_t and long are four bytes,
but double requires 8 byte alignment.

Quote:
but for vector types (eg SSE 128 bit types on intel) it is compiler
and system specific thing, therefore typedef.

OK. You use a single typedef in an implementation dependant file.

I rather suspect that that is superior to my current solution (the
union
described below) -- it allows for strange special cases, but doesn't
impose excessive overhead otherwise.

Quote:
I currently use a union of five or six different types, but there's
nothing in the standard which guarantees it (although I've yet to
have it fail in practice).

It never fails, (although I should say "never say never"Smile).

Given what I know of hardware design and architecture, I cannot imagine
it failing. But my knowledge of hardware design and architecture are
somewhat dated, and I've been surprised by other things already.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.