How to fix C++ gcc compile warning for padding of struct - c++

I have the following innocuous looking code:
void myFunc(){
struct stance {
long double interval;
QString name;
};
// [...]
}
When I build this using standard version of gcc on Ubuntu 18.04 I get a warning like this:
MySource.cpp:12: warning: padding size of 'stance' with 8 bytes to
alignment boundary (-wpadded)
I know that this warning shows up because the compiler needs to adjust the padding for my struct to something that I might not have expected and is kind enough to warn me as the user about this.
However, I am trying to have a warning-free build and so the question is, how can I make it explicit in my code in a standard compliant way that the compiler does not need to issue this warning?
So to be clear, I don't want to suppress warnings in my build script, nor using #pragma or similar either. I want to change the code of this struct so that my alignment expectations are explicit and match whatever the compiler wants to do hence not needing the warning to be displayed.

Just disable the warning (or - well, don't enable it, I don't know of any warning set like -Wall or -Wextra that includes it). -Wpadded is not meant to be always enabled, unless you want to always manually specify the necessary padding explicitly.
-Wpadded
Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure. Sometimes when this happens it is possible to rearrange the fields of the structure to reduce the padding and so make the structure smaller.
(emphasis added)
This is one case where it's not possible. long double is 10 bytes, and it requires 16 bytes alignment (4 on x86 Linux); QString is effectively a pointer, so it needs 8 bytes alignment (4 on 32 bit Linux). You can swap them however you want, but if you want to keep natural alignment (and thus best performance) you'll either get 6 + 8 bytes of padding or 8 + 6 bytes of padding.
In general, adding padding is not a problem, happens all the time and there are cases such as this when it's unavoidable. The general rule to keep it at a minimum is to place elements in order of decreasing alignment requirements, but again, it cannot always be avoided.
As mentioned above, the only alternative (keeping good alignment) is making the padding explicit, but it doesn't make much sense (unless you are designing a file format or something and you want to make everything explicit, but in that case you wouldn't use a QString and would pack to 1 byte).
struct stance {
long double interval;
char unused0[6];
QString name;
char unused1[8];
};

I want to change the code of this struct so that my alignment expectations are explicit
It looks like you want the alignof operator and use it with alignas specifier. So you need at least C++11 and you might want std::alignment_of

Related

Is explicit alignment necessary?

After some readings, I understand that compiler has done the padding for structs or classes such that each member can be accessed on its natural aligned boundary. So under what circumstance is it necessary for coders to make explicit alignment to achieve better performance? My question arises from here:
Intel 64 and IA-32 Architechtures Optimization Reference Manual:
For best performance, align data as follows:
Align 8-bit data at any address.
Align 16-bit data to be contained within an aligned 4-byte word.
Align 32-bit data so that its base address is a multiple of four.
Align 64-bit data so that its base address is a multiple of eight.
Align 80-bit data so that its base address is a multiple of sixteen.
Align 128-bit data so that its base address is a multiple of sixteen.
So suppose I have a struct:
struct A
{
int a;
int b;
int c;
}
// size = 12;
// aligned on boundary of: 4
By creating an array of type A, even if I do nothing, it is properly aligned. Then what's the point to follow the guide and make the alignment stronger?
Is it because of cache line split? Assuming the cache line is 64 bytes. With the 6th access of object in the array, the byte starts from 61 to 72, which slows down the program??
BTW, is there a macro in standard library that tells me the alignment requirement based on the running machine by returning a value of std::size_t?
Let me answer your question directly: No, there is no need to explicitly align data in C++ for performance.
Any decent compiler will properly align the data for underlying system.
The problem would come (variation on above) if you had:
struct
{
int w ;
char x ;
int y ;
char z ;
}
This illustrates the two common structure alignment problems.
(1) It is likely a compiler would insert (2) 3 alignment bytes after both x and z. If there is no padding after x, y is unaligned. If there is no padding after z, w and x will be unaligned in arrays.
The instructions are you are reading in the manual are targeted towards assembly language programmers and compiler writers.
When data is unaligned, on some systems (not Intel) it causes an exception and on others it take multiple processor cycles to fetch and write the data.
The only time I can thing of when you want explicit alignment is when you are directly copying/casting data between your struct to a char* for serialization in some type of binary protocol.
Here unexpected padding may cause problems with a remote user of your protocol.
In pseudocode:
struct Data PACKED
{
char code[3];
int val;
};
Data data = { "AB", 24 };
char buf[20];
memcpy(buf, data, sizeof(data));
send (buf, sizeof(data);
Now if our protocol expects 3 octets of code followed by a 4 octet integer value for val, we will run into problems if we use the above code. Since padding will introduce problems for us. The only way to get this to work is for the struct above to be packed (allignment 1)
There is indeed a facility in the language (it's not a macro, and it's not from the standard library) to tell you the alignment of an object or type. It's alignof (see also: std::alignment_of).
To answer your question: In general you should not be concerned with alignment. The compiler will take care of it for you, and in general/most cases it knows much, much better than you do how to align your data.
The only case where you'd need to fiddle with alignment (see alignas specifier) is when you're writing some code which allows some possibly less aligned data type to be the backing store for some possibly more aligned data type.
Examples of things that do this under the hood are std::experimental::optional and boost::variant. There's also facilities in the standard library explicitly for creating such a backing store, namely std::aligned_storage and std::aligned_union.
By creating an array of type A, even if I do nothing, it is properly aligned. Then what's the point to follow the guide and make the alignment stronger?
The ABI only describes how to use the data elements it defines. The guideline doesn't apply to your struct.
Is it because of cache line split? Assuming the cache line is 64 bytes. With the 6th access of object in the array, the byte starts from 61 to 72, which slows down the program??
The cache question could go either way. If your algorithm randomly accesses the array and touches all of a, b, and c then alignment of the entire structure to a 16-byte boundary would improve performance, because fetching any of a, b, or c from memory would always fetch the other two. However if only linear access is used or random accesses only touch one of the members, 16-byte alignment would waste cache capacity and memory bandwidth, decreasing performance.
Exhaustive analysis isn't really necessary. You can just try and see what alignas does for performance. (Or add a dummy member, pre-C++11.)
BTW, is there a macro in standard library that tells me the alignment requirement based on the running machine by returning a value of std::size_t?
C++11 (and C11) have an alignof operator.

What does the "padding class 'Tester' with 4 bytes" warning mean?

For this simplified test case:
#include <map>
class Tester {
int foo;
std::map<int, int> smap;
};
int main() {
Tester test;
return 0;
}
I get the following compiler warning:
$ clang++ -std=c++98 -Weverything test.cc
test.cc:5:24: warning: padding class 'Tester' with 4 bytes to align 'smap' [-Wpadded]
std::map<int, int> smap;
^
Can anyone explain what this warning means, and how I should address it?
There's no real problem here. In C and C++, the compiler is allowed to insert padding after struct members to provide better alignment, and thus allow faster memory access. In this case, it looks like has decided to place smap on an 8-byte alignment. Since an int is almost certainly four bytes, the warning is telling you that there are four bytes of wasted space in the middle of the struct.
If there were more members of the struct, then one thing you could try would be to switch the order of the definitions. For example, if your Tester had members:
struct Tester {
int foo;
std::map<int, int> smap;
int bar;
};
then it would make sense to place the two ints next to each other to optimise alignment and avoid wasted space. However, in this case, you only have two members, and if you switch them around then the compiler will probably still add four bytes of padding to the end of the struct in order to optimise the alignment of Testers when placed inside an array.
I'm assuming you're compiling this on a 64-bit system.
On 64-bit systems, pointers are 8 bytes. Compilers will align structure members to natural boundaries, so an 8-byte pointer will start at an offset in a structure that is a multiple of 8 bytes.
Since int is only four bytes, the compiler inserted 4 bytes of "padding" after foo, so that smap is on an 8-byte boundary.
Edit: While smap is not a pointer, but a std::map, the same logic applies. I'm not sure what the exact rules for alignment of objects are, but the same thing is happening.
What to do? Nothing. Your code is perfectly fine, the compiler is just letting you know that this has taken place. There's absolutely nothing to worry about. -Weverything means turn on every possible warning, which is probably excessive for most all compilations.
Your compiler on your sytsem chose to give pointers on your 64bit system 8 bytes, int in the struct has 4 bytes. Similar problems/warnings are occurring to me a lot those days working with older code examples so I had to dig deeper.
To make it short, int was defined in the 60's with no 64 bit system, no Gigabytes of storage nor GB of ram in mind.
To solve your error message use size_t (size type) instead of int when necessary - in your case with the map stl since it is programmed to run on multiple different systems.
With size_t your compiler can choose itself what byte size it needs if it compiles on a 32 bit system or a 64 bit system or arm or what ever and the message is gone and you won't even have to modify your code no matter what system you may compile your code for in the future.

Why do gcc and NVCC (g++) see two different structure sizes?

I am trying to add CUDA to an existing single threaded C program that was written sometime in the late 90s.
To do this I need to mix two languages, C and C++ (nvcc is a c++ compiler).
The problem is that the C++ compiler sees a structure as a certain size, while the C compile sees the same structure as a slightly different size. Thats bad. I am really puzzled by this because I can't find a cause for a 4 byte discrepancy.
/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o
My C++ looks like
#include <stdio.h>
#include <stdlib.h>
#include "assert.h"
extern "C"
{
#include "structInfo.h" //contains the structure declaration
}
...
and my C files look like
#include "structInfo.h"
...
with structInfo.h looking like
struct TB {
int nbranch, nnode, root, branches[NBRANCH][2];
double lnL;
} tree;
...
My make file looks like
PRGS = prog
CC = cc
CFLAGS=-std=gnu99 -m32
CuCC = nvcc
CuFlags =-arch=sm_20
LIBS = -lm -L/usr/local/cuda-5.0/lib -lcuda -lcudart
all : $(PRGS)
prog:
$(CC) $(CFLAGS) prog.c gpu.o $(LIBS) -o prog
gpu.o:
$(CuCC) $(CuFlags) -c gpu.cu
Some people asked me why I didn't use a different host compilation option. I think the host compilation option has been deprecated since 2 release ago? Also it never appeared to do what it said it would do.
nvcc warning : option 'host-compilation' has been deprecated and is ignored
GPUs require natural alignment for all data, e.g. a 4-byte int needs to be aligned to a 4-byte boundary and an 8-byte double or long long needs to have 8-byte alignment. CUDA enforces this for host code as well to make sure structs are as compatible as possible between the host and device portions of the code. x86 CPUs on the other hand do not generally require data to be naturally aligned (although performance penalty may result from a lack of alignment).
In this case, CUDA needs to align the double component of the struct to an 8-byte boundary. Since an odd number of int components preceed the double, this requires padding. Switching the order of components, i.e. putting the double component first, does not help because in an array of such structs each struct would have to be 8-byte aligned and the size of the struct therefore must be a multiple of 8 bytes to accomplish that, which also requires padding.
To force gcc to align doubles in the same way CUDA does, pass the flag -malign-double.
Seems like different padding applied by 2 compilers: one is working with 4-byte alignment and the other with at least 8-byte alignment. You should be able to force the alignment you want by compiler-specific #pragma directives (check your compiler documentation about the specific #pragma).
There is no guarantee that two different C compilers will use the same representation for the same type -- unless they both conform to some external standard (an ABI) that specifies the representation in sufficient detail.
It's most likely a difference in padding, where one compiler requires a double to be 4-byte aligned and the other requires it to be 8-byte aligned. Both choices are perfectly valid as far as the C and C++ standards are concerned.
You can investigate this in more detail by printing out the sizes and offsets of all the members of your structure:
printf("nbranch: size %3u offset %3u\n",
(unsigned)sizeof tree.nbranch,
(unsigned)offsetof(struct TB, nbranch));
/* and similarly for the other members */
There may be a compiler-specific way to specify a different alignment, but such techniques are not always safe.
The ideal solution would be to use the same compiler for the C and C++ code. C is not a subset of C++, but it generally shouldn't be too difficult to modify existing C code so it compiles as C++.
Or you might be able to rearrange your structure definition so that both compilers happen to lay it out the same way. Placing the double member first is likely to work. This is still not guaranteed to work, and it could break with future versions of either compiler, but it's probably good enough.
Don't forget that there could also be padding at the very end of the structure; this is sometimes necessary to guarantee proper alignment for arrays of structures. Look at sizeof (struct TB) and compare it to the size and offset of the last declared member.
Another possibility: Insert explicit unused members to force a consistent alignment. For example, suppose if you have:
struct foo {
uint16_t x;
uint32_t y;
};
and one compiler puts y at 16 bits, and the other puts it at 32 bits with 16 bits of padding. If you change the definition to:
struct foo {
uint16_t x;
uint16_t unused_padding;
uint32_t y;
};
then you're more likely to have x and y have the same offset under both compilers. You'll still have to experiment to make sure everything is consistent.
Since the C and C++ code are going to be part of the same program (right?), you shouldn't have to worry about things like varying byte order. If you wanted to transmit values of your structure type between separate programs, say by storing them in files or transmitting them over a network, you might need to define a consistent way to serialize a structure value into a sequence of bytes and vice versa.

Determining the alignment of C/C++ structures in relation to its members

Can the alignment of a structure type be found if the alignments of the structure members are known?
Eg. for:
struct S
{
a_t a;
b_t b;
c_t c[];
};
is the alignment of S = max(alignment_of(a), alignment_of(b), alignment_of(c))?
Searching the internet I found that "for structured types the largest alignment requirement of any of its elements determines the alignment of the structure" (in What Every Programmer Should Know About Memory) but I couldn't find anything remotely similar in the standard (latest draft more exactly).
Edited:
Many thanks for all the answers, especially to Robert Gamble who provided a really good answer to the original question and the others who contributed.
In short:
To ensure alignment requirements for structure members, the alignment of a structure must be at least as strict as the alignment of its strictest member.
As for determining the alignment of structure a few options were presented and with a bit of research this is what I found:
c++ std::tr1::alignment_of
not standard yet, but close (technical report 1), should be in the C++0x
the following restrictions are present in the latest draft: Precondition:T shall be a complete type, a reference type, or an array of
unknown bound, but shall not be a function type or (possibly
cv-qualified) void.
this means that my presented use case with the C99 flexible array won't work (this is not that surprising since flexible arrays are not standard c++)
in the latest c++ draft it is defined in the terms of a new keyword - alignas (this has the same complete type requirement)
in my opinion, should c++ standard ever support C99 flexible arrays, the requirement could be relaxed (the alignment of the structure with the flexible array should not change based on the number of the array elements)
c++ boost::alignment_of
mostly a tr1 replacement
seems to be specialized for void and returns 0 in that case (this is forbidden in the c++ draft)
Note from developers: strictly speaking you should only rely on the value of ALIGNOF(T) being a multiple of the true alignment of T, although in practice it does compute the correct value in all the cases we know about.
I don't know if this works with flexible arrays, it should (might not work in general, this resolves to compiler intrinsic on my platform so I don't know how it will behave in the general case)
Andrew Top presented a simple template solution for calculating the alignment in the answers
this seems to be very close to what boost is doing (boost will additionally return the object size as the alignment if it is smaller than the calculated alignment as far as I can see) so probably the same notice applies
this works with flexible arrays
use Windbg.exe to find out the alignment of a symbol
not compile time, compiler specific, didn't test it
using offsetof on the anonymous structure containing the type
see the answers, not reliable, not portable with c++ non-POD
compiler intrinsics, eg. MSVC __alignof
works with flexible arrays
alignof keyword is in the latest c++ draft
If we want to use the "standard" solution we're limited to std::tr1::alignment_of, but that won't work if you mix your c++ code with c99's flexible arrays.
As I see it there is only 1 solution - use the old struct hack:
struct S
{
a_t a;
b_t b;
c_t c[1]; // "has" more than 1 member, strictly speaking this is undefined behavior in both c and c++ when used this way
};
The diverging c and c++ standards and their growing differences are unfortunate in this case (and every other case).
Another interesting question is (if we can't find out the alignment of a structure in a portable way) what is the most strictest alignment requirement possible. There are a couple of solutions I could find:
boost (internally) uses a union of variety of types and uses the boost::alignment_of on it
the latest c++ draft contains std::aligned_storage
The value of default-alignment shall be the most stringent alignment requirement for any C++ object type whose size is no greater than Len
so the std::alignment_of< std::aligned_storage<BigEnoughNumber>>::value should give us the maximum alignment
draft only, not standard yet (if ever), tr1::aligned_storage does not have this property
Any thoughts on this would also be appreciated.
I have temporarily unchecked the accepted answer to get more visibility and input on the new sub-questions
There are two closely related concepts to here:
The alignment required by the processor to access a particular object
The alignment that the compiler actually uses to place objects in memory
To ensure alignment requirements for structure members, the alignment of a structure must be at least as strict as the alignment of its strictest member. I don't think this is spelled out explicitly in the standard but it can be inferred from the the following facts (which are spelled out individually in the standard):
Structures are allowed to have padding between their members (and at the end)
Arrays are not allowed to have padding between their elements
You can create an array of any structure type
If the alignment of a structure was not at least as strict as each of its members you would not be able to create an array of structures since some structure members some elements would not be properly aligned.
Now the compiler must ensure a minimum alignment for the structure based on the alignment requirements of its members but it can also align objects in a stricter fashion than required, this is often done for performance reasons. For example, many modern processors will allow access to 32-bit integers in any alignment but accesses may be significantly slower if they are not aligned on a 4-byte boundary.
There is no portable way to determine the alignment enforced by the processor for any given type because this is not exposed by the language, although since the compiler obviously knows the alignment requirements of the target processor it could expose this information as an extension.
There is also no portable way (at least in C) to determine how a compiler will actually align an object although many compilers have options to provide some level of control over the alignment.
I wrote this type trait code to determine the alignment of any type(based on the compiler rules already discussed). You may find it useful:
template <class T>
class Traits
{
public:
struct AlignmentFinder
{
char a;
T b;
};
enum {AlignmentOf = sizeof(AlignmentFinder) - sizeof(T)};
};
So now you can go:
std::cout << "The alignment of structure S is: " << Traits<S>::AlignmentOf << std::endl;
The following macro will return the alignment requirement of any given type (even if it's a struct):
#define TYPE_ALIGNMENT( t ) offsetof( struct { char x; t test; }, test )
Note: I probably borrowed this idea from a Microsoft header at some point way back in my past...
Edit: as Robert Gamble points out in the comments, this macro is not guaranteed to work. In fact, it will certainly not work very well if the compiler is set to pack elements in structures. So if you decide to use it, use it with caution.
Some compilers have an extension that allows you obtain the alignment of a type (for example, starting with VS2002, MSVC has an __alignof() intrinsic). Those should be used when available.
As the others mentioned, its implementation dependant. Visual Studio 2005 uses 8 bytes as the default structure alignment. Internally, items are aligned by their size - a float has 4 byte alignment, a double uses 8, etc.
You can override the behavior with #pragma pack. GCC (and most compilers) have similar compiler options or pragmas.
It is possible to assume a structure alignment if you know more details about the compiler options that are in use. For example, #pragma pack(1) will force alignment on the byte level for some compilers.
Side note: I know the question was about alignment, but a side issue is padding. For embedded programming, binary data, and so forth -- In general, don't assume anything about structure alignment if possible. Rather use explicit padding if necessary in the structures. I've had cases where it was impossible to duplicate the exact alignment used in one compiler to a compiler on a different platform without adding padding elements. It had to do with the alignment of structures inside of structures, so adding padding elements fixed it.
If you want to find this out for a particular case in Windows, open up windbg:
Windbg.exe -z \path\to\somemodule.dll -y \path\to\symbols
Then, run:
dt somemodule!CSomeType
I don't think memory layout is guaranteed in any way in any C standard. This is very much vendor and architect-dependent. There might be ways to do it that work in 90% of cases, but they are not standard.
I would be very glad to be proven wrong, though =)
I agree mostly with Paul Betts, Ryan and Dan. Really, it's up to the developer, you can either keep the default alignment symanic's which Robert noted about (Robert's explanation is just the default behaviour and not by any means enforced or required), or you can setup whatever alignment you want /Zp[##].
What this means is that if you have a typedef with floats', long double's, uchar's etc... various assortments of arrays's included. Then have another type which has some of these oddly shaped members, and a single byte, then another odd member, it will simply be aligned at whatever preference the make/solution file defines.
As noted earlier, using windbg's dt command at runtime you can find out how the compiler laid out the structure in memory.
You can also use any pdb reading tool like dia2dump to extract this info from pdb's statically.
Modified from Peeter Joot's Blog
C structure alignment is based on the biggest size native type in the structure, at least generally (an exception is something like using a 64-bit integer on win32 where only 32-bit alignment is required).
If you have only chars and arrays of chars, once you add an int, that int will end up starting on a 4 byte boundary (with possible hidden padding before the int member). Additionally, if the structure isn’t a multiple of sizeof(int), hidden padding will be added at the end. Same thing for short and 64-bit types.
Example:
struct blah1 {
char x ;
char y[2] ;
};
sizeof(blah1) == 3
struct blah1plusShort {
char x ;
char y[2] ;
// <<< hidden one byte inserted by the compiler here
// <<< z will start on a 2 byte boundary (if beginning of struct is aligned).
short z ;
char w ;
// <<< hidden one byte tail pad inserted by the compiler.
// <<< the total struct size is a multiple of the biggest element.
// <<< This ensures alignment if used in an array.
};
sizeof(blah1plusShort) == 8
I read this answer after 8 years and I feel that the accepted answer from #Robert is generally right, but mathematically wrong.
To ensure alignment requirements for structure members, the alignment of a structure must be at least as strict as the least common multiple of the alignment of its members. Consider an odd example, where the alignment requirements of members are 4 and 10; in which case the alignment of the structure is LCM(4, 10) which is 20, and not 10. Of course, it is odd to see platforms with such alignment requirement which is not a power of 2, and thus for all practical cases, the structure alignment is equal to the maximum alignment of its members.
The reason for this is that, only if the address of the structure starts with the LCM of its member alignments, the alignment of all the members can be satisfied and the padding between the members and the end of the structure is independent of the start address.
Update: As pointed out by #chqrlie in the comment, C standard does not allow the odd values of the alignment. However this answer still proves why structure alignment is the maximum of its member alignments, just because the maximum happens to be the least common multiple, and thus the members are always aligned relative to the common multiple address.

Are POD types always aligned?

For example, if I declare a long variable, can I assume it will always be aligned on a "sizeof(long)" boundary? Microsoft Visual C++ online help says so, but is it standard behavior?
some more info:
a. It is possible to explicitely create a misaligned integer (*bar):
char foo[5]
int * bar = (int *)(&foo[1]);
b. Apparently, #pragma pack() only affects structures, classes, and unions.
c. MSVC documentation states that POD types are aligned to their respective sizes (but is it always or by default, and is it standard behavior, I don't know)
As others have mentioned, this isn't part of the standard and is left up to the compiler to implement as it sees fit for the processor in question. For example, VC could easily implement different alignment requirements for an ARM processor than it does for x86 processors.
Microsoft VC implements what is basically called natural alignment up to the size specified by the #pragma pack directive or the /Zp command line option. This means that, for example, any POD type with a size smaller or equal to 8 bytes will be aligned based on its size. Anything larger will be aligned on an 8 byte boundary.
If it is important that you control alignment for different processors and different compilers, then you can use a packing size of 1 and pad your structures.
#pragma pack(push)
#pragma pack(1)
struct Example
{
short data1; // offset 0
short padding1; // offset 2
long data2; // offset 4
};
#pragma pack(pop)
In this code, the padding1 variable exists only to make sure that data2 is naturally aligned.
Answer to a:
Yes, that can easily cause misaligned data. On an x86 processor, this doesn't really hurt much at all. On other processors, this can result in a crash or a very slow execution. For example, the Alpha processor would throw a processor exception which would be caught by the OS. The OS would then inspect the instruction and then do the work needed to handle the misaligned data. Then execution continues. The __unaligned keyword can be used in VC to mark unaligned access for non-x86 programs (i.e. for CE).
By default, yes. However, it can be changed via the pack() #pragma.
I don't believe the C++ Standard make any requirement in this regard, and leaves it up to the implementation.
C and C++ don't mandate any kind of alignment. But natural alignment is strongly preferred by x86 and is required by most other CPU architectures, and compilers generally do their utmost to keep CPUs happy. So in practice you won't see a compiler generate misaligned data unless you really twist it's arm.
Yes, all types are always aligned to at least their alignment requirements.
How could it be otherwise?
But note that the sizeof() a type is not the same as it's alignment.
You can use the following macro to determine the alignment requirements of a type:
#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )
Depends on the compiler, the pragmas and the optimisation level. With modern compilers you can also choose time or space optimisation, which could change the alignment of types as well.
Generally it will be because reading/writing to it is faster that way. But almost every compiler has a switch to turn this off. In gcc its -malign-???. With aggregates they are generally aligned and sized based on the alignment requirements of each element within.