Re: [boost] alignment problem in proposed any alternative

Nope, this is totally wrong! chars and arrays of type char are generally the least aligned objects. You can demonstrate that this doesn't work with something like this: void blah() { char c[/* some number */]; any<8> a((double)1.0); std::cout << &a << std::endl; } Tweak the size of c[] until you get &a % 8 != 0. Some compilers optimize stack layout, over-aligning data, but this is true only for SOME compilers on SOME processors with SOME optimization settings. (You can also experiment by defining an additional char variable before the buffer in your any. Where does &a.buffer lie?) I think you are misreading 3.9.2: it is talking about pointers, namely that void * and char * have the same storage and alignment requirements. On Wed, 10 Aug 2005 20:27:16 +0200, <boost-request@lists.boost.org> wrote:
From: "christopher diggins" <cdiggins@videotron.ca> To: "Boost mailing list" <boost@lists.boost.org> Sent: Wednesday, August 10, 2005 1:30 AM Subject: [boost] alignment problem in proposed any alternative
The question I have is whether in practice though are there are any compilers which have stricter alignment requirements on small types (<= sizeof(void*)) than a void pointer. In other words, is it possible with any known compiler to actually throw the runtime error ? Now a moot point, see below.
Unfortunately there is another problem, I am not an expert in interepreting the standard, but AFAICT placement new is guaranteed to return a pointer to properly aligned memory (3.7.3.1 / 2) which I leverage to check that alignment occured. Apparently not every STL implementation does in fact do that (I believe at least dinkumware is guilty of that). Apparently I am wrong about this! 18.4.1.3 provides an exception. (I wonder why I missed the exception 15 chapters later?) Anyway it turns out we can guarantee alignment by simply using a char buffer. According to 3.9/2 the following automatically has no alignment problems: template<int buffer_size> struct any { char buffer[buffer_size]; ... template<typename T> any(const T& x) { if (boost::is_pod<T>::value && (sizeof(T) <= buffer_size)) { memcpy(buffer, &T, N); } else { // new and stuff } } } Christopher Diggins
-- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/

----- Original Message ----- From: "felipe" <pbr@taric.es> To: <boost@lists.boost.org> Sent: Thursday, August 11, 2005 4:09 AM Subject: Re: [boost] alignment problem in proposed any alternative
Nope, this is totally wrong! chars and arrays of type char are generally the least aligned objects. You can demonstrate that this doesn't work with something like this:
void blah() { char c[/* some number */]; any<8> a((double)1.0); std::cout << &a << std::endl; }
That code is completely misleading, yhe question is not what the address of a is!
I think you are misreading 3.9.2: it is talking about pointers, namely that void * and char * have the same storage and alignment requirements.
3.9(2) says: For any complete POD object type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.36) If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value. This has nothing to do with void* and char*, but rather with all POD's. This clearly implies char arrays are stringently aligned. -- Christopher Diggins http://www.cdiggins.com

christopher diggins wrote:
3.9(2) says: For any complete POD object type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.36) If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value.
This has nothing to do with void* and char*, but rather with all POD's.
This clearly implies char arrays are stringently aligned.
Not to me, it doesn't! It doesn't say "can be copied into *any* array of char". And it doesn't say you can use reinterpret_cast to use the char array as an object of T, it says you can store the bytes there then copy them back into a T, without loss of information. You are implying this is OK: #include <cstring> typedef int T; struct S { char a1[3]; char a2[sizeof(T)]; }; int main() { T t; S s; std::memcpy(s.a2, &t, sizeof(T)); T* p = reinterpret_cast<T*>(s.a2); return *p; } That's nonsense. S.a2 is not correctly aligned for an int. jon
participants (3)
-
christopher diggins
-
felipe
-
Jonathan Wakely