473,799 Members | 2,926 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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<typena me 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(alig n(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 2831
On Wed, 24 Sep 2008 07:13:31 +0100, Stephen Horne
<sh********@blu eyonder.co.ukwr ote:

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...@blu eyonder.co.ukwr ote:
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<typena me 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 dummyForAlignme nt ;
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 objektorientier ter Datenverarbeitu ng
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...@gm ail.comwrote:
On Sep 24, 8:13 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
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<typena me 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,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
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-standardalignme nt
* * 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>::ty pe 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 dummyForAlignme nt ;
* * * * 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>::dummyForA lignment' 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 dummyForAlignme nt '. 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...@gm ail.comwrote:
On Sep 24, 8:13 am, Stephen Horne
<sh006d3...@blu eyonder.co.ukwr ote:
[...]
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>::ty pe 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 dummyForAlignme nt ;
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>::dummyForA lignment' 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 dummyForAlignme nt
'. 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 dummyForAlignme nt ;
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 objektorientier ter Datenverarbeitu ng
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******** *************** ***********@d31 g2000hsg.google groups.com...
On Sep 24, 4:43 am, James Kanze <james.ka...@gm ail.comwrote:
On Sep 24, 8:13 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
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
4098
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 words I wouldn't overrun the array. I was told that this is dangerous and that there could be alignment problems if, for example, I wanted to access the char array elements from non-even multiples of sizeof(int). For example, if I had the array: ...
4
17694
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 b;
10
3243
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 suggest so?
67
10762
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 other. All pointers to union types shall have the same representation and alignment requirements as each other. Does it mean that *all* structure (or union) types have the same alignment? Eg. type
14
1960
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 C code, especially design a structure, I pay attention to the order and size of member variables. Because, my boss always says that all variables should be aligned by 4byte boundary, if not a data abort will be occurred on a specific machine such...
5
575
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 system + OS e.g. Windows, Linux, WinCE. I am not quite sure about the alignment of the memory.... soln. 1: should be faster, I am not sure. idx size (bytes) 1 4
10
3825
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 application that the code be speed optimized ) I use reinterpret_cast to alias a block of chars read in from disc as a block of integer "words". My existing code (see simplified code below) appears to work well enough on the platforms available to me,...
1
2083
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 <cstring> #include <cassert> // attempts to extract the alignemnt of a type T
2
236
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
9687
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9541
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10251
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10225
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10027
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6805
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5463
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5585
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4139
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.