473,416 Members | 1,674 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,416 software developers and data experts.

A weird problem on structure and union alignment

Please forgive me for cross-posting. I've post this to
microsoft.publoc.vc.mfc. But I can't get any response. Maybe only MFC-
related topics are cared there.

To begin with code:

union XXX
{
double a;
char b;
double c;
};

XXX s;
size_t n1 = sizeof(XXX);
size_t n2 = __alignof(double);
size_t n3 = __alignof(XXX);

double* p1 = &s.a;
char* p2 = &s.b;
double* p3 = &s.c;
XXX* p4 = &s;

Compiler: VS 2005 + SP1

Output:
n1 = 8
n2 = 8 // the largest member in the union is 8-byte aligned!
n3 = 4 // ???, it should be 4 less than 8
p1 = 0x0012F5B4 // ???, it is not 8-byte aligned!
p2 = 0x0012F5B4 // ditto
p3 = 0x0012F5B4 // ditto
p4 = 0x0012F5B4 // ditto

Below is a related article copied from the site "The Old New Thing".
Because posting new comments to the original post has been disabled,
so I have to put it here. Please note the first comments to the post
by Roger Lipscombe, He/She says: "the C standard states that they must
be aligned suitably for the largest contained member." However, I
can't find any statement in the C standard, Is that implementation-
defined?

Thanks in advance!
================ Quotation ======================
The original link: http://blogs.msdn.com/oldnewthing/ar...25/220195.aspx

Why can't you treat a FILETIME as an __int64?

The FILETIME structure represents a 64-bit value in two parts:

typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME;
You may be tempted to take the entire FILETIME structure and access it
directly as if it were an __int64. After all, its memory layout
exactly matches that of a 64-bit (little-endian) integer. Some people
have written sample code that does exactly this:

pi = (__int64*)&ft; // WRONG
(*pi) += (__int64)num*datepart; // WRONG
Why is this wrong?

Alignment.

Since a FILETIME is a structure containing two DWORDs, it requires
only 4-byte alignment, since that is sufficient to put each DWORD on a
valid DWORD boundary. There is no need for the first DWORD to reside
on an 8-byte boundary. And in fact, you've probably already used a
structure where it doesn't: The WIN32_FIND_DATA structure.

typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
TCHAR cFileName[ MAX_PATH ];
TCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
Observe that the three FILETIME structures appear at offsets 4, 12,
and 20 from the beginning of the structure. They have been thrown off
8-byte alignment by the dwFileAttributes member.

Casting a FILETIME to an __int64 therefore can (and in the
WIN32_FIND_DATA case, will) create a misaligned pointer. Accessing a
misaligned pointer will raise a STATUS_DATATYPE_MISALIGNMENT exception
on architectures which require alignment.

Even if you are on a forgiving platform that performs automatic
alignment fixups, you can still run into trouble. More on this and
other consequences of alignment in the next few entries.

Exercise: Why are the LARGE_INTEGER and ULARGE_INTEGER structures not
affected?

===================================
Comments by Roger Lipscombe

LARGE_INTEGER and ULARGE_INTEGER are unions, and the C standard states
that they must be aligned suitably for the largest contained member --
which is a LONLONG or ULONGLONG, respectively.

Aug 25 '07 #1
5 2602
xmllmx wrote:
Please forgive me for cross-posting. I've post this to
microsoft.publoc.vc.mfc. But I can't get any response. Maybe only MFC-
related topics are cared there.
However, it's off-topic here, as the Standard makes no promises as to
alignment.
To begin with code:

union XXX
{
double a;
char b;
double c;
};

XXX s;
size_t n1 = sizeof(XXX);
size_t n2 = __alignof(double);
size_t n3 = __alignof(XXX);

double* p1 = &s.a;
char* p2 = &s.b;
double* p3 = &s.c;
XXX* p4 = &s;
There are other microsoft.public groups, as well as
comp.windows.ms.programmer. Follow-up set to that group.

Aug 25 '07 #2
xmllmx wrote:
Please forgive me for cross-posting. I've post this to
microsoft.publoc.vc.mfc. But I can't get any response. Maybe only MFC-
related topics are cared there.

To begin with code:

union XXX
{
double a;
char b;
double c;
};

XXX s;
size_t n1 = sizeof(XXX);
size_t n2 = __alignof(double);
size_t n3 = __alignof(XXX);

double* p1 = &s.a;
char* p2 = &s.b;
double* p3 = &s.c;
XXX* p4 = &s;

Compiler: VS 2005 + SP1

Output:
n1 = 8
n2 = 8 // the largest member in the union is 8-byte aligned!
n3 = 4 // ???, it should be 4 less than 8
p1 = 0x0012F5B4 // ???, it is not 8-byte aligned!
p2 = 0x0012F5B4 // ditto
p3 = 0x0012F5B4 // ditto
p4 = 0x0012F5B4 // ditto

I posted the code below on an earlier article on alignment. I added
some of your code to it and printed some stuff. I don't think I have
SP1 installed - however with VS 2005 I get consistent numbers, namely
alignment of XXX is 8.
template <typename T>
struct noreference
{
typedef T type;
};

template <typename T>
struct noreference<T&>
{
typedef T type;
};

template <typename T>
struct alignof_static
{
struct Helper1 { T v; };
struct Helper2 { char c; Helper1 v; };

static const unsigned value = sizeof(Helper2)-sizeof(Helper1);
};

template <typename T>
struct alignof_noref_static
{
static const unsigned value = alignof_static<typename
noreference<T>::type >::value;
};

template <typename T>
unsigned alignof()
{
return alignof_static<T>::value;
}

template <typename T>
unsigned alignof_noref()
{
return alignof_noref_static<T>::value;
}

union XXX
{
double a;
char b;
double c;
};

#include <iostream>
int main()
{
std::cout << alignof<XXX>() << "\n";
std::cout << alignof<double>() << "\n";
std::cout << __alignof(XXX) << "\n";
std::cout << __alignof(double) << "\n";
}
Aug 25 '07 #3
On Aug 26, 7:09 am, Gianni Mariani <gi3nos...@mariani.wswrote:
xmllmx wrote:
Please forgive me for cross-posting. I've post this to
microsoft.publoc.vc.mfc. But I can't get any response. Maybe only MFC-
related topics are cared there.
To begin with code:
union XXX
{
double a;
char b;
double c;
};
XXX s;
size_t n1 = sizeof(XXX);
size_t n2 = __alignof(double);
size_t n3 = __alignof(XXX);
double* p1 = &s.a;
char* p2 = &s.b;
double* p3 = &s.c;
XXX* p4 = &s;
Compiler: VS 2005 + SP1
Output:
n1 = 8
n2 = 8 // the largest member in the union is 8-byte aligned!
n3 = 4 // ???, it should be 4 less than 8
p1 = 0x0012F5B4 // ???, it is not 8-byte aligned!
p2 = 0x0012F5B4 // ditto
p3 = 0x0012F5B4 // ditto
p4 = 0x0012F5B4 // ditto

I posted the code below on an earlier article on alignment. I added
some of your code to it and printed some stuff. I don't think I have
SP1 installed - however with VS 2005 I get consistent numbers, namely
alignment of XXX is 8.

template <typename T>
struct noreference
{
typedef T type;

};

template <typename T>
struct noreference<T&>
{
typedef T type;

};

template <typename T>
struct alignof_static
{
struct Helper1 { T v; };
struct Helper2 { char c; Helper1 v; };

static const unsigned value = sizeof(Helper2)-sizeof(Helper1);

};

template <typename T>
struct alignof_noref_static
{
static const unsigned value = alignof_static<typename
noreference<T>::type >::value;

};

template <typename T>
unsigned alignof()
{
return alignof_static<T>::value;

}

template <typename T>
unsigned alignof_noref()
{
return alignof_noref_static<T>::value;

}

union XXX
{
double a;
char b;
double c;

};

#include <iostream>
int main()
{
std::cout << alignof<XXX>() << "\n";
std::cout << alignof<double>() << "\n";
std::cout << __alignof(XXX) << "\n";
std::cout << __alignof(double) << "\n";

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Maybe your computer is running on a 64-bit CPU. Mine is 32-bit.

Aug 26 '07 #4
xmllmx wrote:
p1 = 0x0012F5B4 // ???, it is not 8-byte aligned!
Why do you expect it to be? I believe that in a 32-bit architecture a
64-bit double doesn't necessarily need to be aligned at the 64-bit
boundary, but it's ok for it to be at the 32-bit boundary without
suffering any penalty.
Aug 26 '07 #5
xmllmx wrote:
....
>
Maybe your computer is running on a 64-bit CPU. Mine is 32-bit.
No - mine is 32 bit but I doubt that makes any difference.

Aug 26 '07 #6

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

Similar topics

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...
3
by: Muhammad Farooq-i-Azam | last post by:
Hi, I am trying to define an arp structure but having problem doing so. I think I have define the correct arp structure but I find myself in a strange problem. The size of structure that I have...
5
by: MeJohn | last post by:
Hello, I have a question about the layout of the fields in a structure. I have read in a paper that if two structures contain an initial sequence of fields, all of which have compatible types,...
12
by: candy_init | last post by:
I recently came across the following CAST macro which can cast anything to any other thing: #define CAST(new_type,old_object) (*((new_type *)&old_object)) union { char ch; int i; }...
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...
28
by: kyle york | last post by:
Greetings, Why does the C standard require the members of a structure not be re-ordered (6.2.5.20)? Padding is allowed, and platform dependent, which means one cannot rely on the exact layout...
56
by: Bruce. | last post by:
I would like to allocate a structure size of 1024 bytes but I want the compiler to do the calculation for me. typedef struct { int var1; int var2; int var3; char ...
76
by: jacob navia | last post by:
Since standard C doesn't provide any way for the programmer to direct the compiler as to how to layout structures, most compilers provide some way to do this, albeit in different forms. ...
8
by: rahul | last post by:
How is the memory allocated for structures? I need to optimize the memory usage and bit fields are not doing the trick. Any details about the memory allocation for the structures would be a...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
0
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,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
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...

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.