Re: Alignment
On Mar 2, 4:13 pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
"James Kanze" <james.ka...@gmail.com> wrote in message
news:891084b3-ce7d-4a9a-b893-14499e22a2bc@j35g2000yqh.googlegroups.com...
On Feb 27, 4:15 am, "Chris M. Thomasson" <n...@spam.invalid>
wrote:
<better_cs_...@yahoo.com> wrote in message
news:eab8ea3f-5616-4fd8-b2b0-16f86fe0b7a8@q1g2000vbn.googlegroups.com.=
...
Please consider the two definitions below:
Foo foo;
unsigned char foo[sizeof(Foo)];
Are these guaranteed to have the same alignment, or will the
second definition have an alignment that is only modulo 1?
You can attempt to calculate alignment of `Foo' objects like this:
Which isn't what he needs, but...
___________________________________________________________________
#include <cstddef>
#include <cstdio>
struct Foo {
char a;
int b;
double c;
Foo(int b) {
// [...];
}
};
template<typename T>
size_t get_type_alignment() {
struct aligner {
char m_pad;
T m_obj;
};
return offsetof(aligner, m_obj);
This is undefined behavior if T isn't a POD (and Foo isn't). It
won't compile with at least one compiler I use.
DOH!!! Yes, of course! My mistake. Thanks!
What about something like the following hack James?:
______________________________________________________________________
#include <cstddef>
#include <cstdio>
#include <climits>
#include <new>
template<typename T, std::size_t CUSTOM_ALIGN = 0U>
class alignment {
struct aligner_1 {
T m_obj;
};
struct aligner_2 {
char m_pad;
aligner_1 m_obj;
};
public:
enum constant {
ALIGN_SIZE = (! CUSTOM_ALIGN)
? sizeof(aligner_2) - sizeof(aligner_1)
: CUSTOM_ALIGN,
BUFFER_SIZE = sizeof(aligner_1) + (size_t)ALIGN_SIZE - 1U
};
static void* align_ptr(void* ptr) {
return ALIGN_SIZE > 1
? (void*)((((size_t)ptr) + ((size_t)ALIGN_SIZE - 1U))
& ~((size_t)ALIGN_SIZE - 1U))
: ptr;
}
private:
typedef char sassert[
ALIGN_SIZE > 0 &&
BUFFER_SIZE > 0 &&
ALIGN_SIZE <= INT_MAX &&
BUFFER_SIZE <= INT_MAX &&
ALIGN_SIZE > 1 ? ! ((size_t)ALIGN_SIZE % 2U) : 1 &&
sizeof(std::size_t) == sizeof(void*) ? 1 : -1
];
};
My basic question is why? It doesn't enforce the alignment of
the buffer; it allocates a slightly larger buffer, and then
determines the first aligned address in it. A solution using a
union will force the compiler to align correctly to begin with.
[...]
Does that compile on all your compilers?
Probably.
Odd that the broken code which used `offsetof' macro on
non-POD type compiles file on Comeau without warning.
It's more or less a library issue. G++ can detect the problem
because offsetof is defined as something like:
#define offsetof( a, b ) __buildin_offsetof( a, b )
and handled by the compiler. The library you're using with
Comeau probably exploits some other undefined behavior; the
classical implementation is something like:
#define offsetof( a, b ) ((size_t)(&((a*)0)->b))
This dereferences a null pointer, but in a way such that most
compilers won't actually generate any code for it. So it never
causes a compiler error, nor a core dump (but in some cases
where virtual bases are involved, it might give a wrong answer).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34