473,378 Members | 1,527 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

alignment issues

I understand that the next C++ standard will have features to handle
the alignment of data types. This is good, but a bit late for me!

I've been using some template trickery to handle alignment issues for
some time. What I usually want is a type that takes the same amount of
space and has the same alignment as some other type, but which doesn't
have constructors, destructors etc. The idea is that initialisation
and cleanup can be done with casts, placement new and explicit
destructor calls, but that this memory-only type can live in a union
or whatever.

To get the alignment of an existing type, I use something like...

template<typename T>
class CAlign_Of
{
private:
struct CDummy
{
char m_Char;
T m_T;
};

public:
enum { Align = ((size_t) &(((CDummy*) 0)->m_T)) };
};

Which I figure should be portable to any platform where char is a
single byte (though I don't think even that is guaranteed).

To create the replacement type, however, is a bit more of a problem.
To create a type the right size, you just use a template struct
containing and array of chars, but getting the alignment right is the
problem.

Using template specialisation to present a range of options isn't too
problematic, but how to code the options.

At the moment I have a #ifdef conditional compilation solution. The
Microsoft VC++ block uses the __declspec(align(n)) non-portable
solution, which annoyingly only accepts literal integers (as opposed
to compile-time constants) for the parameter. But for other compilers,
all I can come up with is the following...

template<size_t S>
struct CSpace_For<S, 1 { UInt8 m [ S ]; };

template<size_t S>
struct CSpace_For<S, 2 { UInt16 m [(S+1)/2]; };

template<size_t S>
struct CSpace_For<S, 4 { UInt32 m [(S+3)/4]; };

template<size_t S>
struct CSpace_For<S, 8 { UInt64 m [(S+7)/8]; };

However, there is no guarantee that any compiler will use the needed
alignment for these types. It can depend on the platform, the
compiler, and compiler settings.

Up until now, I haven't worried because I always knew what compiler I
was targetting. Now I have a problem - I'm writing a code generator
that needs to generate variant-record-like types. Those variants will
have members with types defined outside the generated code, which may
not be considered aggregates. The whole point of this project is to
sell it to unsuspecting victims, and I'd like to minimise the victim
aspect.

From what I've seen in other code generators, the usual practice is to
assume a pessimistic alignment, allocate a bit of extra memory, and do
an align-to-boundary calculation manually such as...

(address + 15) & ~15

This worries me because pessimistic may not be pessimistic enough as
extra hardward features are added that I'm not aware of - I undestand
that SIMD instructuctions require aligned data, for example, with
potentially larger alignments than 8 bytes (16 bytes certainly) - and
who knows what the next 5 years will bring.

So...

1. Is there a good portable solution now?
2. What will the standard C++ solution be?
3. How consistent are compilers in their non-standard alignment
handling right now? - e.g. does GCC c++ support an __alignof
extension similar to that on MS VC++?

Sep 24 '08 #1
8 2794
On Wed, 24 Sep 2008 07:13:31 +0100, Stephen Horne
<sh********@blueyonder.co.ukwrote:

Spot the stupid mistake...
>template<size_t S>
struct CSpace_For<S, 2 { UInt16 m [(S+1)/2]; };

template<size_t S>
struct CSpace_For<S, 4 { UInt32 m [(S+3)/4]; };

template<size_t S>
struct CSpace_For<S, 8 { UInt64 m [(S+7)/8]; };
Should be...

template<size_t S>
struct CSpace_For<S, 2 { UInt16 m [(S+1) & ~1]; };

etc

Sep 24 '08 #2
On Sep 24, 8:13 am, Stephen Horne <sh006d3...@blueyonder.co.ukwrote:
I understand that the next C++ standard will have features to
handle the alignment of data types. This is good, but a bit
late for me!
I've been using some template trickery to handle alignment
issues for some time. What I usually want is a type that takes
the same amount of space and has the same alignment as some
other type, but which doesn't have constructors, destructors
etc. The idea is that initialisation and cleanup can be done
with casts, placement new and explicit destructor calls, but
that this memory-only type can live in a union or whatever.
To get the alignment of an existing type, I use something
like...
template<typename T>
class CAlign_Of
{
private:
struct CDummy
{
char m_Char;
T m_T;
};
public:
enum { Align = ((size_t) &(((CDummy*) 0)->m_T)) };
};
Which I figure should be portable to any platform where char
is a single byte (though I don't think even that is
guaranteed).
It is. By definition, char is a byte, and all other types
consist of an integral number of bytes.
To create the replacement type, however, is a bit more of a
problem. To create a type the right size, you just use a
template struct containing and array of chars, but getting the
alignment right is the problem.
So...
1. Is there a good portable solution now?
2. What will the standard C++ solution be?
3. How consistent are compilers in their non-standard alignment
handling right now? - e.g. does GCC c++ support an __alignof
extension similar to that on MS VC++?
Technically, I don't think that there is a solution 100%
guaranteed by the standard. Practically, I use the following:

namespace GlobalPrivate {

template< typename T, bool isSmaller >
struct AlignTypeDetail ;

template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;

template< typename T >
struct AlignTypeDetail< T, true >
{
typedef char type ;
} ;

template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof( T ) <
sizeof( U )) >::type
type ;
} ;
}

template< typename T >
union MaxAlignFor
{
typename GlobalPrivate::AlignType< T, char >::type c ;
typename GlobalPrivate::AlignType< T, short >::type s ;
typename GlobalPrivate::AlignType< T, int >::type i ;
typename GlobalPrivate::AlignType< T, long >::type l ;
typename GlobalPrivate::AlignType< T, long long >::type ll ;
typename GlobalPrivate::AlignType< T, float >::type f ;
typename GlobalPrivate::AlignType< T, double >::type d ;
typename GlobalPrivate::AlignType< T, long double >::type ld ;
typename GlobalPrivate::AlignType< T, void* >::type pc ;
typename GlobalPrivate::AlignType< T, MaxAlign* >::type ps ;
typename GlobalPrivate::AlignType< T, void (*)() >::type pf ;
} ;

and then declare a union:

union
{
MaxAlignFor< T dummyForAlignment ;
unsigned char data[ sizeof( T ) ] ;
} ;

This supposes that 1) the required alignment will not be more
than the alignment of one of the types in my MaxAlignFor union,
and 2) it will not be more than the size of the type. The
latter is more or less guaranteed by the standard (albeit very
indirectly); the former seems safe for now, and if it does cause
problems in the future, it shouldn't be any real problem to add
another type to the MaxAlignFor union. (All such types must be
POD, but I can't imagine that being a problem.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Sep 24 '08 #3

I already posted one thankyou, but it didn't appear, so thankyou
again.

Sep 25 '08 #4
On Sep 24, 4:43*am, James Kanze <james.ka...@gmail.comwrote:
On Sep 24, 8:13 am, Stephen Horne <sh006d3...@blueyonder.co.ukwrote:
I understand that the next C++ standard will have features to
handle thealignmentof data types. This is good, but a bit
late for me!
I've been using some template trickery to handlealignment
issues for some time. What I usually want is a type that takes
the same amount of space and has the samealignmentas some
other type, but which doesn't have constructors, destructors
etc. The idea is that initialisation and cleanup can be done
with casts, placement new and explicit destructor calls, but
that this memory-only type can live in a union or whatever.
To get thealignmentof an existing type, I use something
like...
template<typename T>
class CAlign_Of
{
* private:
* * struct CDummy
* * {
* * *charm_Char;
* * * T * *m_T;
* * };
* public:
* * enum { Align = ((size_t) &(((CDummy*) 0)->m_T)) };
};
Which I figure should be portable to any platform wherechar
is a single byte (though I don't think even that is
guaranteed).

It is. *By definition,charis a byte, and all other types
consist of an integral number of bytes.
To create the replacement type, however, is a bit more of a
problem. *To create a type the right size, you just use a
template struct containing and array of chars, but getting the
alignmentright is the problem.
So...
1. *Is there a good portable solution now?
2. *What will the standard C++ solution be?
3. *How consistent are compilers in their non-standardalignment
* * handling right now? - e.g. does GCC c++ support an __alignof
* * extension similar to that on MS VC++?

Technically, I don't think that there is a solution 100%
guaranteed by the standard. *Practically, I use the following:

* * namespace GlobalPrivate {

* * template< typename T, bool isSmaller >
* * struct AlignTypeDetail ;

* * template< typename T >
* * struct AlignTypeDetail< T, false >
* * {
* * * * typedef T type ;
* * } ;

* * template< typename T >
* * struct AlignTypeDetail< T, true >
* * {
* * * * typedefchartype ;
* * } ;

* * template< typename T, typename U >
* * struct AlignType
* * {
* * * * typedef typename AlignTypeDetail< U, (sizeof( T ) <
sizeof( U )) >::type
* * * * * * * * * * * * * * type ;
* * } ;
* * }

* * template< typename T >
* * union MaxAlignFor
* * {
* * * * typename GlobalPrivate::AlignType< T,char>::type * * * *c ;
* * * * typename GlobalPrivate::AlignType< T, short >::type * * * s ;
* * * * typename GlobalPrivate::AlignType< T, int >::type * ** * i ;
* * * * typename GlobalPrivate::AlignType< T, long >::type * * * *l ;
* * * * typename GlobalPrivate::AlignType< T, long long >::type * ll ;
* * * * typename GlobalPrivate::AlignType< T, float >::type * * * f ;
* * * * typename GlobalPrivate::AlignType< T,double>::type * * *d ;
* * * * typename GlobalPrivate::AlignType< T, longdouble>::type ld ;
* * * * typename GlobalPrivate::AlignType< T, void* >::type * * * pc ;
* * * * typename GlobalPrivate::AlignType< T, MaxAlign* >::type * ps ;
* * * * typename GlobalPrivate::AlignType< T, void (*)() >::type *pf ;
* * } ;

and then declare a union:

* * union
* * {
* * * * MaxAlignFor< T dummyForAlignment ;
* * * * unsignedchar* *data[ sizeof( T ) ] ;
* * } ;
Pretty nifty solution here. When I try to compile this though I get
the errors:

1>c:\msvc_2007-orcas\dev\test\main.cpp(52) : error C2065: 'T' :
undeclared identifier
1>c:\msvc_2007-orcas\test\main.cpp(52) : error C2621: member '<unnamed-
tag>::dummyForAlignment' of union '<unnamed-tag>' has copy constructor
1>c:\msvc_2007-orcas\test\main.cpp(53) : error C2065: 'T' : undeclared
identifier
1>c:\msvc_2007-orcas\test\main.cpp(53) : error C2070: ''unknown-
type'': illegal sizeof operand
1>c:\msvc_2007-orcas\test\main.cpp(53) : warning C4200: nonstandard
extension used : zero-sized array in struct/union

where line 52 is the line 'MaxAlignFor< T dummyForAlignment '. What
am I doing wrong?
Thanks
Oct 13 '08 #5
On Oct 13, 3:54 am, ma740988 <ma740...@gmail.comwrote:
On Sep 24, 4:43 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 24, 8:13 am, Stephen Horne
<sh006d3...@blueyonder.co.ukwrote:
[...]
Technically, I don't think that there is a solution 100%
guaranteed by the standard. Practically, I use the following:
namespace GlobalPrivate {
template< typename T, bool isSmaller >
struct AlignTypeDetail ;
template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;
template< typename T >
struct AlignTypeDetail< T, true >
{
typedefchartype ;
} ;
template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof( T ) <
sizeof( U )) >::type
type ;
} ;
}
template< typename T >
union MaxAlignFor
{
typename GlobalPrivate::AlignType< T,char>::type c ;
typename GlobalPrivate::AlignType< T, short >::type s ;
typename GlobalPrivate::AlignType< T, int >::type i ;
typename GlobalPrivate::AlignType< T, long >::type l ;
typename GlobalPrivate::AlignType< T, long long >::type ll ;
typename GlobalPrivate::AlignType< T, float >::type f ;
typename GlobalPrivate::AlignType< T,double>::type d ;
typename GlobalPrivate::AlignType< T, longdouble>::type ld ;
typename GlobalPrivate::AlignType< T, void* >::type pc ;
typename GlobalPrivate::AlignType< T, MaxAlign* >::type ps ;
typename GlobalPrivate::AlignType< T, void (*)() >::type pf ;
} ;
and then declare a union:
union
{
MaxAlignFor< T dummyForAlignment ;
unsignedchar data[ sizeof( T ) ] ;
} ;
Pretty nifty solution here. When I try to compile this though
I get the errors:
1>c:\msvc_2007-orcas\dev\test\main.cpp(52) : error C2065: 'T' :
undeclared identifier
1>c:\msvc_2007-orcas\test\main.cpp(52) : error C2621: member '<unnamed-
tag>::dummyForAlignment' of union '<unnamed-tag>' has copy constructor
1>c:\msvc_2007-orcas\test\main.cpp(53) : error C2065: 'T' : undeclared
identifier
1>c:\msvc_2007-orcas\test\main.cpp(53) : error C2070: ''unknown-
type'': illegal sizeof operand
1>c:\msvc_2007-orcas\test\main.cpp(53) : warning C4200: nonstandard
extension used : zero-sized array in struct/union
where line 52 is the line 'MaxAlignFor< T dummyForAlignment
'. What am I doing wrong?
What is T in the union? The error messages say you haven't
defined it. There is a requirement here (although I didn't
mention it) that the instantiation argument be a complete type;
something like:

class MyClass ;
union
{
MaxAlignFor< MyClass dummyForAlignment ;
unsigned char data[ sizeof( MyClass ) ] ;
} ;

doesn't work.

(The code above is copy/pasted from my actual headers, with the
union copy/pasted from my current implementation of Fallible,
and I compile it with g++, Sun CC and VC++ without problems.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Oct 13 '08 #6
On 09/24/08 01:13, Stephen Horne wrote:
[snip]
To get the alignment of an existing type, I use something like...
[snip]
Why not use boost's alignment_of:

http://www.boost.org/doc/libs/1_36_0...gnment_of.html

?
Oct 27 '08 #7
also, please check this crap out:

http://groups.google.com/group/comp....2bd4db8de1aad2

Wow! ;^D

Oct 28 '08 #8
"ma740988" <ma******@gmail.comwrote in message
news:e8**********************************@d31g2000 hsg.googlegroups.com...
On Sep 24, 4:43 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 24, 8:13 am, Stephen Horne <sh006d3...@blueyonder.co.ukwrote:
I understand that the next C++ standard will have features to
handle thealignmentof data types. This is good, but a bit
late for me!
[...]
Pretty nifty solution here.
[...]

Check this NASTY hack out:

http://groups.google.com/group/comp....7e0d0e97c5e1d9

use the offsetof macro to attempt to determine max alignment. Here is a
pre-alpha fairly crude C++ non-blocking region allocator which uses the
hack:

http://webpages.charter.net/appcore/...em_thread.html

here is some more context:

http://groups.google.com/group/comp....38a7a8a4f5a7cb

Oct 28 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: J. Campbell | last post by:
I posted a question some time back about accessing a char array as an array of words. In order not to overrun the char array, I padded it with enough 0x00 bytes to ensure that when accessed as...
4
by: Shashi | last post by:
Can somebody explain how the byte alignment for structures work, taking the following example and considering: byte of 1 Byte word of 2 Bytes dword of 4 Bytes typedef struct { byte a; word...
10
by: j0mbolar | last post by:
for any pointer to T, does a pointer to T have different or can have different alignment requirement than a pointer to pointer to T? if so, where is the exact wording in the standard that would...
67
by: S.Tobias | last post by:
I would like to check if I understand the following excerpt correctly: 6.2.5#26 (Types): All pointers to structure types shall have the same representation and alignment requirements as each...
14
by: gamja | last post by:
Hi all. This is my first post on this group. Nice to meet you, cool guys~! I'm on system programming on various embedded systems and understand very well the byte alignment issues. When I write...
5
by: pt | last post by:
Hi, i am wonderng what is faster according to accessing speed to read these data structure from the disk in c/c++ including alignment handling if we access it on little endian system 32 bits...
10
by: Lionel B | last post by:
Greetings, I have some code that is to read unformatted data from disc and interpret it as blocks of unsigned integers. In an attempt to achieve efficiency (it is pretty essential for my...
1
by: Chris Thomasson | last post by:
I found some time to work a little more on my C++ allocator project. Here is some of the basic alignment code that I am thinking about using: ---------------- #include <cstdio> #include...
2
by: =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?= | last post by:
On Sep 22, 10:45 am, Nick Keighley <nick_keighley_nos...@hotmail.com> wrote: Only problem is that then entire frame in memory might have strange alignment.
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.