Specifically, this came up in a discussion:
Memory consuption wise, is there a possibility that using a struct of two ints take more memory than just two ints?
Or, in language terms:
#include <iostream>
struct S { int a, b; };
int main() {
std::cout << (sizeof(S) > sizeof(int) * 2 ? "bigger" : "the same") << std::endl;
}
Is there any reasonable1 (not necessarily common or current) environment where this small program would print bigger?
1To clarify, what I meant here is systems (and compilers) developed and produced in some meaningful quantity, and specifically not theoretical examples constructed just to prove the point, or one-off prototypes or hobbyist creations.
Is there any reasonable (not necessarily common or current) environment where this small program would print bigger?
Not that I know of. I know that's not completely reassuring, but I have reason to believe there is no such environment due to the requirements imposed by the C++ standard.
In a standard-compliant† compiler the following hold:
(1) arrays cannot have any padding between elements, due to the way they can be accessed with pointersref;
(2) standard layout structs may or may not have padding after each member, but not at the beginning, because they are layout-compatible with "shorter"-but-equal standard layout structsref;
(3) array elements and struct members are properly alignedref;
From (1) and (3), it follows that the alignment of a type is less than or equal to its size. Were it greater, an array would need to add padding to have all its elements aligned. For the same reason, the size of a type is always a whole multiple of its alignment.
This means that in a struct as the one given, the second member will always be properly aligned—whatever the size and alignment of ints—if placed right after the first member, i.e., no interstitial padding is required. Under this layout, the size of the struct is also already a multiple of its alignment, so no trailing padding is required either.
There is no standard-compliant set of (size, alignment) values that we can pick that makes this structure need any form of padding.
Any such padding would then need a different purpose. However, such a purpose seems elusive. Suppose there is an environment that needs this padding for some reason. Whatever the reason for the padding is, it would likely‡ also apply in the case of arrays, but from (1) we know that it cannot.
But suppose such an environment truly exists and we want a C++ compiler for it. It could support this extra required padding in arrays by simply making ints larger that much, i.e. by putting the padding inside the ints. This would in turn once more allow the struct to be the same size as two ints and leave us without a reason to add padding.
† A compiler—even one otherwise not-standard-compliant—that gets any of these wrong is arguably buggy, so I'll ignore those.
‡ I guess that in an environment where arrays and structures are primitives there might be some underlying distinction that allows us to have unpadded arrays and padded structs, but again, I don't know of any such thing in use.
In your specific example, struct S { int a, b; };, I cannot see any reasonable argument for padding. int should be naturally aligned already, and if it is, int * can and should be the natural representation for pointers, and there is no need for S * to be any different. But in general:
A few rare systems have pointers with different representations, where e.g. int * is represented as just an integer representing a "word" address, and char * is a combination of a word address and a byte offset into that word (where the byte offset is stored in otherwise unneeded high bits of the word address). Dereferencing a char * happens in software by loading the word, and then masking and shifting to get the right byte.
On such implementations, it may make sense to ensure all structure types have a minimal alignment, even if it's not necessary for the structure's members, just so that that byte offset mess isn't necessary for pointers to that structure. Meaning it's reasonable that given struct S { char a, b; };, sizeof(S) > 2. Specifically, I'd expect sizeof(S) == sizeof(int).
I've never personally worked with such implementations, so I don't know if they do indeed produce such padding. But an implementation that does so would be reasonable, and at the very least very close to an existing real-world implementation.
I know this is not what you asked for, it's not in the spirit of your question (as you probably have standard layout classes in mind), but strictly answering just this part:
Memory consuption wise, is there a possibility that using a struct of
two ints take more memory than just two ints?
the answer is kinda... yes:
struct S
{
int a;
int b;
virtual ~S() = default;
};
with the pedantic note that C++ doesn't have structs, it has classes. struct is a keyword that introduces the declaration/definition of a class.
It would not be totally implausible that a system which can only access memory in 64-bit chunks might have an option to use a 32-bit "int" size for compatibility with other programs that could get tripped up of uint32_t promotes to a larger type. On such a system, a struct with an even number of "int" values would likely not have extra padding, but one with an odd number of values might plausibly do so.
From a practical perspective, the only way a struct with two int values would need padding would be if the alignment of a struct was more than twice as coarse as that of "int". That would in turn require either that the alignment of structures be coarser than 64 bits, or that the size of int be smaller than 32 bits. The latter situation wouldn't be unusual in and of itself, but combining both in a fashion that would make struct alignment more than twice as coarse as int alignment would seem very weird.
Theoretically padding is used to provide efficient way of accessing memory area.If adding padding to 2 integer variable would increase the efficient than yes it can have padding.But practically I haven't came across any structure with 2 integer have padding bits.
Related
I know that this is all implementation specific, but for the sake of example let's assume that for a certain modern computer:
int takes up a whole WORD
short takes up half a WORD
Will the short actually take up less memory, or will it just be stored in the first half of a WORD with unused memory in the second half? Will a C/C++ compiler ever try to pack two or more smaller variables into a single WORD, or will this space always be wasted?
That depends a lot on usage.
You can usually force the compiler to optimize for space.
Objects are more optimally accessed when aligned to a memory boundary that is a multiple of their size (On most architectures).
As such the compiler may inject space to get better alignment.
This usually happens when objects of different sizes are required to be beside each other.
The compiler is NOT allowed to rearrange the order of variables in a structure (if they are in the same private/public/protected section).
I do not believe there are any requirements of ordering of variables in the local stack frame. So the compiler should be able to optimally pack the local variables and use all available space optimally (even potentially re-use space for POD variables or never use space if it can keep it in a register).
But if you have a structure that is using the same size objects.
struct X
{
short var1;
short var2;
}
Then most likely there will be no padding in the above structure (no guarantee but it's highly likely there is no padding).
Because of point 3 above: If you want to help your compiler optimally pack a structure then it definitely makes it easier for the compiler to order your members from largest to smallest as this makes the packing without needing padding much easier (but the standard does not impose any requirements on padding).
// if we assume sizeof(int) == 8
struct Y
{
char x; // 1 byte;
// Compiler will (prob) insert 7 bytes of padding here.
// to make sure that y is on an 8 byte boundry
// for most effecient reads.
int y;
char z; // 1 byte
// Compiler will (prob) insert 7 bytes of padding here.
// to make sure that the whole structure has a size
// that is a multiple of 8 (the largest object)
// This allows for optimal packing of arrays of type
// Y.
};
The compiler can still achieve optimal packing and fast access if you arrange the object like this:
struct Y
{
int y;
char x;
char z;
// probably add 6 bytes of padding.
// So that we get optimal access to objects in an array.
};
for the sake of example let's assume that for a certain modern computer:
If we assume a modern good compiler like clang or g++ on normal standard architecture machine. Even if we assume not optimizing for speed.
Will the short actually take up less memory
Yes. Modern compiler will pack objects as much as possible and would probably use only the memory required. Note: most compiler be default will optimize for speed so will maintain optimal alignment for speed so will pad if they have to (if objects in a structure that they can not re-order have different sizes).
or will it just be stored in the first half of a WORD with unused memory in the second half?
Unlikely unless there is some requirement that the compiler must maintain. Like order of a structure.
Will a C/C++ compiler ever try to pack two or more smaller variables into a single WORD
Yes. All the time. The default is usually. 1 Optimize for speed. 2 Optimize for size (not always mutually exclusive). You can also force modern compilers to optimize for space and pack structures without padding.
or will this space always be wasted?
Unlikely.
Suppose I have the following struct:
typedef struct {
int mID;
struct in_addr mIP;
size_t dataSize;
// Another structure
fairness_structure str;
bool ack;
bool stability;
bool stop_message;
}HeaderType;
As you know, the size of a struct would vary due to its alignment. How to fill in the padding between fields with some data, say with zeros?
Just initialize the structure with memset, and the padding will be filled as well.
memset(&mystruct, 0, sizeof(HeaderType));
If you want to really only fill the pads, you can can cast the pointer to char* and do the arithmetics. But in this case you MUST know how the compiler padded the structure, or enforce it yourself with #pragma pack.
You can use offsetof() macro to get the offset of struct members.
char *off = (char *)&mystruct + offsetof(HeaderType, ack);
char *pad_start = off + sizeof(mystruct.ack);
char *pad_end = (char *)&mystruct + offsetof(HeaderType, stability);
Bedtime reading: The Lost Art of C Structure Packing
Controlling the contents of padding bits and bytes does not seem very useful. But if you write the contents of a structure to a file with a single write or fwrite call, You probably care about the padding and may want to make sure they have consistent values, preferably 0, at all times. Not that is matters when you read the contents back from the file, but in order for the file contents to be predictable and reproducible. Some development tools are known to produce unpredictable contents in object or executable files exactly for this reason, making it very difficult to rebuild from source and check signatures.
So if you really need this, you want a simple and portable method.
The bad news is the C Standard does not have a generic solution for this.
The only guaranty about the contents of padding bytes and bits the standard makes is for uninitialized structures of static storage. Padding is guarantied to be zero in this case (in a hosted environment). In practice, this is also true of initialized structures because it is simple enough for compiler writers to do so.
What about local structures with automatic storage? If they are not initialized, both fields and padding contents are indeterminate. If you just clear the bytes with a memset(&s, 0, sizeof(s)) the padding will be cleared and you can start modifying struct members... Bad news again: the C standard describes as Unspecified behaviour The value of padding bytes when storing values in structures or unions (6.2.6.1).
In other words, storing values in structure members can have side effects on the contents of padding bits and bytes. The compiler is allowed to generate code that does that and it may be more efficient to do so.
The method described by Marek beyond the simple memset is very cumbersome to use, especially if you have bitfields. In practice, clearing the structures before you initialize the fields manually seems the simplest way to achieve the purpose, and I have not seen a compilers that takes advantage of the Standard's leniency concerning the padding bytes. If you pass the structures by value, all bets are off as the compiler may generate code that does not copy the padding.
As a conclusion: if you use local structures, clear them with memset before use and do not pass them by value. There is no guaranty padding will keep a 0 value, but that's the best you can do.
Usually data is aligned at power of two addresses depending on its size.
How should I align a struct or class with size of 20 bytes or another non-power-of-two size?
I'm creating a custom stack allocator so I guess that the compiler wont align data for me since I'm working with a continuous block of memory.
Some more context:
I have an Allocator class that uses malloc() to allocate a large amount of data.
Then I use void* allocate(U32 size_of_object) method to return the pointer that where I can store whether objects I need to store.
This way all objects are stored in the same region of memory and it will hopefully fit in the cache reducing cache misses.
C++11 has the alignof operator specifically for this purpose. Don't use any of the tricks mentioned in other posts, as they all have edge cases or may fail for certain compiler optimisations. The alignof operator is implemented by the compiler and knows the exact alignment being used.
See this description of c++11's new alignof operator
Although the compiler (or interpreter) normally allocates individual data items on aligned boundaries, data structures often have members with different alignment requirements. To maintain proper alignment the translator normally inserts additional unnamed data members so that each member is properly aligned. In addition the data structure as a whole may be padded with a final unnamed member. This allows each member of an array of structures to be properly aligned. http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86
This says that the compiler takes care of it for you, 99.9% of the time. As for how to force an object to align a specific way, that is compiler specific, and only works in certain circumstances.
MSVC: http://msdn.microsoft.com/en-us/library/83ythb65.aspx
__declspec(align(20))
struct S{ int a, b, c, d; };
//must be less than or equal to 20 bytes
GCC: http://gcc.gnu.org/onlinedocs/gcc-3.4.0/gcc/Type-Attributes.html
struct S{ int a, b, c, d; }
__attribute__ ((aligned (20)));
I don't know of a cross-platform way (including macros!) to do this, but there's probably neat macro somewhere.
Unless you want to access memory directly, or squeeze maximum data in a block of memory you don't worry about alignment -- the compiler takes case of that for you.
Due to the way processor data buses work, what you want to avoid is 'mis-aligned' access. Usually you can read a 32 bit value in a single access from addresses which are multiples of four; if you try to read it from an address that's not such a multiple, the CPU may have to grab it in two or more pieces. So if you're really worrying about things at this level of detail, what you need to be concerned about is not so much the overall struct, as the pieces within it. You'll find that compilers will frequently pad out structures with dummy bytes to ensure aligned access, unless you specifically force them not to with a pragma.
Since you've now added that you actually want to write your own allocator, the answer is straight-forward: Simply ensure that your allocator returns a pointer whose value is a multiple of the requested size. The object's size itself will already come suitably adjusted (via internal padding) so that all member objects themselves are properly aligned, so if you request sizeof(T) bytes, all your allocator needs to do is to return a pointer whose value is divisible by sizeof(T).
If your object does indeed have size 20 (as reported by sizeof), then you have nothing further to worry about. (On a 64-bit platform, the object would probably be padded to 24 bytes.)
Update: In fact, as I only now came to realize, strictly speaking you only need to ensure that the pointer is aligned, recursively, for the largest member of your type. That may be more efficient, but aligning to the size of the entire type is definitely not getting it wrong.
How should I align a struct or class with size of 20 bytes or another non-power-of-two size?
Alignment is CPU-specific, so there is no answer to this question without, at least, knowing the target CPU.
Generally speaking, alignment isn't something that you have to worry about; your compiler will have the rules implemented for you. It does come up once in a while, like when writing an allocator. The classic solution is discussed in The C Programming Language (K&R): use the worst possible alignment. malloc does this, although it's phrased as, "the pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object."
The way to do that is to use a union (the elements of a union are all allocated at the union's base address, and the union must therefore be aligned in such a way that each element could exist at that address; i.e., the union's alignment will be the same as the alignment of the element with the strictest rules):
typedef Align long;
union header {
// the inner struct has the important bookeeping info
struct {
unsigned size;
header* next;
} s;
// the align member only exists to make sure header_t's are always allocated
// using the alignment of a long, which is probably the worst alignment
// for the target architecture ("worst" == "strictest," something that meets
// the worst alignment will also meet all better alignment requirements)
Align align;
};
Memory is allocated by creating an array (using somthing like sbrk()) of headers large enough to satisfy the request, plus one additional header element that actually contains the bookkeeping information. If the array is called arry, the bookkeeping information is at arry[0], while the pointer returned points at arry[1] (the next element is meant for walking the free list).
This works, but can lead to wasted space ("In Sun's HotSpot JVM, object storage is aligned to the nearest 64-bit boundary"). I'm aware of a better approach that tries to get a type-specific alignment instead of "the alignment that will work for anything."
Compilers also often have compiler-specific commands. They aren't standard, and they require that you know the correct alignment requirements for the types in question. I would avoid them.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Size of struct with a single element
Given any type A and the following struct:
struct S
{
A a;
};
Are there any cases where sizeof(S) is greater than sizeof(A)?
For example, can sizeof(std::array<T, n>) be greater than sizeof(T[n])?
Being able to use A inside of S means that the compiler already has knowledge of the structure of A and has already added padding bytes to it. I see no reason for it to add further padding to S, as it already is aligned.
While the struct can be padded, on all systems I know, the compiler will pad so that the alignment of the structure is the same as the largest alignment of its members. It does this so that an array of the structure will always be correctly aligned.
So:
struct S
{
char a;
} // Size 1, no padding
struct S2
{
unsigned int a;
char b;
} // Size 8, 3 bytes padding (assuming 32 bit integer)
Edit: Note, that compilers can also add internal padding, to keep the alignment of the data correct.
The C/C++ standard doesn't specify any of these detail. What you want is the C ABI (application binary interface) for the system you're running on, which should specify default layout for structs (compilers can choose to override this if they see fit, see also #pragma pack). For an example, look at the X86_64 ABI page 13, which states:
Aggregates and Unions Structures and unions assume the alignment of
their most strictly aligned compo- nent. Each member is assigned to
the lowest available offset with the appropriate alignment. The size
of any object is always a multiple of the object‘s alignment. An array
uses the same alignment as its elements, except that a local or global
array variable of length at least 16 bytes or a C99 variable-length
array variable always has alignment of at least 16 bytes. Structure
and union objects can require padding to meet size and alignment
constraints. The contents of any padding is undefined.
The relevant text is 5.3.3/2 "When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array."
An implementation is allowed to add extra bytes for the purposes of array bound checks (e.g. "this is the 5th array member out of a total of 12", as this is within the leeway granted here and not explicitly banned by any other requirement.
(Presumably, that implementation would also store a "1 out of 1" indication for structs that aren't part of an array; in C++ the types S and S[1] are quite interchangable)
ISO/IEC 14882(10/2008) 1.8.5:
Unless it is a bit-field (9.6), a most derived object shall have a non-zero size and shall occupy one or more
bytes of storage. Base class subobjects may have zero size.
This means that an empty struct has a size of 1 although the size of "all data members" (there are none) is zero, as would a zero-length bitfield (according to 9.6.2 this would have to be an unnamed bitfield, though).
Neither really applies though, as you did not ask for an empty struct, and your member is named (so it can't be zero-length).
Similar would be true if your a member was of type void, but 3.9.5 does not allow that ("[...] the void types are incomplete types (3.9.1). Objects shall not be defined to have an incomplete type").
So in short, as you said you are mostly interested about what the standard says: no, the standard does not explicitly define such a case.
However, it also does not forbid the compiler to add padding or apply alignment, and most compilers will pad/align structures to machine word size by default (unless explicitly told otherwise).
A struct can be padded (it's allowed for compilers do whatever they like, for example padding a six-octet type to eight to align with page boundaries). It's unlikely to happen though.
std::array will be bigger, because it stores some extra information in the class, like the array's length. Typing on auto-pilot; read std::vector without thinking.
If A is a byte then struct will align to the nearest boundary. Rather if A is smaller than a boundary then yes it will be bigger. EX a struct of RGB is the same size as a struct of RGBA.
I don't have sample code that will do that. You have to dump memory and see the holes. If you then assume that everything is size aligned and cast a structure onto a wad of memory you will have bad data. This is why WADs had padding for alignment. As your compositions get more complicated, the ability to close holes by the compiler is diminished. Eventually padding will be introduced and any assumptions of memory layout will become more and more wrong.
Question 1
I have a struct like,
struct foo
{
int a;
char c;
};
When I say sizeof(foo), I am getting 8 on my machine. As per my understanding, 4 bytes for int, 1 byte for char and 3 bytes for padding. Is that correct? Given a struct like the above, how will I find out how many bytes will be added as padding?
Question 2
I am aware that sizeof can be used to calculate the size of an array. Mostly I have seen the usage like (foos is an array of foo)
sizeof(foos)/sizeof(*foos)
But I found that the following will also give same result.
sizeof(foos) / sizeof(foo)
Is there any difference in these two? Which one is preferred?
Question 3
Consider the following statement.
foo foos[] = {10,20,30};
When I do sizeof(foos) / sizeof(*foos), it gives 2. But the array has 3 elements. If I change the statement to
foo foos[] = {{10},{20},{30}};
it gives correct result 3. Why is this happening?
Any thoughts..
Answer 1
Yes - your calculation is correct. On your machine, sizeof(int) == 4, and int must be 4-byte aligned.
You can find out about the padding by manually adding the sizes of the base elements and subtracting that from the size reported by sizeof(). You can predict the padding if you know the alignment requirements on your machine. Note that some machines are quite fussy and give SIGBUS errors when you access misaligned data; others are more lax but slow you down when you access misaligned data (and they might support '#pragma packed' or something similar). Often, a basic type has a size that is a power of 2 (1, 2, 4, 8, 16) and an n-byte type like that must be n-byte aligned. Also, remember that structures have to be padded so that an array of structures will leave all elements properly aligned. That means the structure will normally be padded up to a multiple of the size of the most stringently aligned member in the structure.
Answer 2
Generally, a variant on the first is better; it remains correct when you change the base type of the array from a 'foo' to a 'foobar'. The macro I customarily use is:
#define DIM(x) (sizeof(x)/sizeof(*(x)))
Other people have other names for the same basic operation - and you can put the name I use down to pollution from the dim and distant past and some use of BASIC.
As usual, there are caveats. Most notably, you can't apply this meaningfully to array arguments to a function or to a dynamically allocated array (using malloc() et al or new[]); you have apply to the actual definition of an array. Normally the value is a compile-time constant. Under C99, it could be evaluated at runtime if the array is a VLA - variable-length array.
Answer 3
Because of the way initialization works when you don't have enough braces. Your 'foo' structure must have two elements. The 10 and the 20 are allocated to the first row; the 30 and an implicit 0 are supplied to the second row. Hence the size is two. When you supply the sub-braces, then there are 3 elements in the array, the first components of which have the values 10, 20, 30 and the second components all have zeroes.
The padding is usually related to the size of the registers on the hist CPU - in your case, you've got a 32-bit CPU, so the "natural" size of an int is 4 bytes. It is slower and more difficult for the CPU to access quantities of memory smaller than this size, so it is generally preferable to align values onto 4-byte boundaries. The struct thus comes out as a multiple of 4 bytes in size. Most compilers will allow you to modify the amount of padding used (e.g. with "#pragma"s), but this should only be used where the memory footprint of the struct is absolutely critical.
"*foos" references the first entry in the foos array. "foo" references (a single instance of) the type. So they are essentially the same. I would use sizeof(type) or sizeof(array[0]) myself, as *array is easier to mis-read.
In your first example, you are not intialising the array entries correctly. Your struct has 2 members so you must use { a, b } to initialise each member of the array. So you need the form { {a, b}, {a, b}, {a, b} } to correctly initialise the entries.
To find out how much padding you have, simply add up the sizeof() each element of the structure, and subtract this sum from the sizeof() the whole structure.
You can use offsetof() to find out exactly where the padding is, in more complex structs. This may help you to fill holes by rearranging elements, reducing the size of the struct as a whole.
It is good practice to explicitly align structure elements, by manually inserting padding elements so that every element is guaranteed to be "naturally aligned". You can reuse these padding elements for useful data in the future. If you ever write a library that will require a stable ABI, this will be a required technique.