Re: A portable way of pointer alignment
"Ian Collins" <ian-news@hotmail.com> wrote in message
news:7uokorF4ikU1@mid.individual.net...
Chris M. Thomasson wrote:
"Alf P. Steinbach" <alfps@start.no> wrote:
Formally it doesn't, in practice it may and probably will, depending on
the compiler.
After all there's not much magic underneath.
Of course that also applies to the macro that you posted. :-)
Well, I only use that macro in C where everything is a POD. For C++ I use
something like:
http://pastebin.org/96326
Which seems to be working fine for everything I throw at it so far,
including reference types.
C doesn't have reference types.
I know. I only use the macro in C. I use the following for C++:
http://pastebin.org/96326
I also believe that it has a problem with reference types.
Hm?
For instance, I cannot get the following to compile and run correctly:
<snip>
Then when I run the program, it crashes. What am I doing wrong here Alf?
Remember you can't dynamically allocate reference types, so they aren't
applicable to the original question.
You can dynamically allocate objects that contain references. Anyway,
dynamic memory allocation is not the issue here. It's aligning objects. So,
if I had say:
struct object
{
int& m_int;
object(int& int_) : m_int(int_) {}
};
and a buffer:
char buffer[1024];
and I wanted to carve objects out of that buffer. Given that, I would need
to be able to get the alignment of the reference type `object::m_int'. So,
here is a program that can solve the problem by using my alignment
technique:
__________________________________________________________________________
#include <cstddef>
#if ! defined (ALIGN_UINTPTR_TYPE)
# define ALIGN_UINTPTR_TYPE std::size_t
#endif
template<typename T, std::size_t A = 0>
class align
{
typedef ALIGN_UINTPTR_TYPE uintptr_type;
typedef char sassert
[
sizeof(uintptr_type) == sizeof(void*) ? 1 : -1
];
struct object
{
T m_object;
object(T o) : m_object(o) {}
};
struct aligner
{
char m_pad;
object m_object;
};
public:
enum constant
{
result = (! A) ? (sizeof(aligner) - sizeof(object)) : A,
bufsize = result + sizeof(object) - 1
};
struct address
{
static T* calc(void* ptr)
{
return (T*)((((uintptr_type)ptr) + result - 1) &
((uintptr_type)(-result)));
}
static T const* calc(void const* ptr)
{
return (T const*)((((uintptr_type)ptr) + result - 1) &
((uintptr_type)(-result)));
}
};
};
#define ALIGN_OF(T) align<T>::result
#include <iostream>
#include <new>
struct object
{
int& m_int;
object(int& int_) : m_int(int_) {}
};
int
main()
{
int x = -666;
char raw_buffer[1024];
object* align_buffer = align<object>::address::calc(raw_buffer);
object* obj = new (align_buffer) object(x);
obj->m_int = 42;
std::cout << "ALIGN_OF(object) == " << ALIGN_OF(object) << std::endl;
std::cout << "raw_buffer == " << (void*)raw_buffer << std::endl;
std::cout << "align_buffer == " << align_buffer << std::endl;
std::cout << "x == " << x << std::endl;
return 0;
}
__________________________________________________________________________
This is example of where I might need the alignment of a reference type...
Alf's function (or your macro) won't work with reference types because the
dummy struct has a reference member but no constructor.
I still cannot get it to compile even if I add a dummy constructor:
_______________________________________________________________
#include <cstddef>
#include <iostream>
template< typename T >
inline std::size_t alignmentOf()
{
struct X
{
char bah;
T t;
X(T t_) : t(t_) {}
};
return offsetof( X, t );
}
struct object
{
char m_1[2];
double m_d[6];
long m_2[2];
short m_3[14];
};
int
main()
{
std::cout << "alignmentOf<object&> == "
<< alignmentOf<object&>()
<< std::endl;
return 0;
}
_______________________________________________________________
I get the following from Comeau:
_______________________________________________________________
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 16: error: expression must have a constant value
return offsetof( X, t );
^
detected during instantiation of
"size_t alignmentOf<T>() [with T=object &]" at line 34
1 error detected in the compilation of "ComeauTest.c".
_______________________________________________________________
Humm...