How are they structured in memory in C ++?

Is the way to build C ++ structures defined standard or at least common for compilers?

I have a structure where one of its members needs to be aligned on 16-byte boundaries, and that would be easier if I could guarantee the ordering of the fields.

In addition, for non-virtual classes, the address of the first element can also be the address of the structure?

I am most interested in GCC and MSVS.

+6
c ++ gcc struct memory visual-c ++
source share
6 answers

C and C ++ ensure that the fields are laid out in memory in the same order as you define them. For C ++, which is only guaranteed for type POD 1 (anything that would be legal as C struct [Edit: C89 / 90 - not, for example, C99 VLA] would also qualify as POD).

The compiler can insert additions between members and / or at the end of the structure. Most compilers give you some way of managing this (e.g. #pragma pack(N) ), but it depends on the compilers.

1 Well, there is one corner case that they did not think about, where it is not guaranteed for the POD type - the access specifier violates the order guarantee:

 struct x { int x; int y; public: int z; }; 

This is a POD type, but public: between y and z means that they can theoretically be reordered. I am sure that this is purely theoretical - I do not know of any compiler that changes the order of members in this situation (and if the memory does not succeed today even worse than usual, this is fixed in C ++ 0x).

Edit: The relevant parts of the standard (at least most of them) are §9 / 4:

A POD-struct is a cumulative class that does not have non-volatile data members such as a pointer to a member, a non-POD-struct, POD-union (or an array of such types) or a link, and does not have a user-defined copy assignment operator and non-user-defined destructor.

and §8.5.1 / 1:

An aggregate is an array or class (section 9) declared constructors (12.1), no private or protected non-static data elements (section 11), without base classes (section 10) and there are no virtual functions (10.3).

and §9.2 / 12:

... the distribution order of non-static data elements separated by an access specifier is not specified (11.1).

Although this was somewhat limited to paragraph 9.2 / 17:

A pointer to a POD structure object properly transformed using reinterpret_cast points to its initial member ...

Therefore (even if it is preceded by a public: first member you define must be the first in memory. Other members separated by public: qualifiers can theoretically be reordered.

I should also point out that there is room for debate about this. In particular, there is also a rule in 9.2 / 14:

Two types of POD-struct (section 9) are compatible with layouts if they have the same number of non-static data elements, and the corresponding non-static data members (in order) have types compatible with layouts (3.9).

Therefore, if you have something like:

 struct A { int x; public: int y; public: int z; }; 

The format is required to be compatible with:

 struct B { int x; int y; int z; }; 

I am sure that this / was intended to mean that the members of the two structures should be located equally in memory. Since the second, obviously, cannot regroup its members, the first should not be either. Unfortunately, the standard never defines what “layout compatibility” means, which makes the argument weak at best.

+12
source share

C ++ inherits from c the need / desire to work effectively on many platforms and, therefore, leaves some things to the compiler. In addition to the need for elements to appear in this order, this is one of them.

But many compilers support #pragma and options that allow you to take control of the packaging. See the compiler documentation.

+5
source share

Is the way to build C ++ structures set by the standard, or at least common to compilers?

There is no guarantee in the standard. I will not depend on compilers with the same alignment

I have a structure where one of its members must be aligned by 16 byte boundaries, and it would be easier if I can guarantee the order of the field.

Compilers will not change the order of the fields.

Here are some links on how to install them for both GCC and MSVC:
For GCC: http://developer.apple.com/mac/library/documentation/DeveloperTools/gcc-4.0.1/gcc/Structure_002dPacking-Pragmas.html
MSVC: http://msdn.microsoft.com/en-us/library/ms253935(VS.80).aspx and http://msdn.microsoft.com/en-us/library/2e70t5y1(VS.80). aspx

I would save them as structures and use extern "C" to make sure that it works correctly. Maybe not necessary, but it will definitely work.

+4
source share

C struct (and C ++ POD, for compatibility) is required by the standard for sequential linking .

The only difference between compilers is alignment, but, fortunately, support for MSVC and GCC #pragma pack .

+2
source share

If you want to see the memory layout of all types of classes in memory under MSVC, add the /d1reportAllClassLayout to the compiler command line.

If you want to see how one class is put, add /d1reportSingleClassLayoutNNNNN , where NNNNN is the name of the class.

+1
source share

Structures are laid out sequentially in memory. However, the alignment method in memory depends on the operating system.

For things larger than 4 bytes, there is a difference between Windows and Linux. Linux aligns them as if they were 4 bytes, so for example, double (8 bytes) could start with p + 4, p + 8, p + 12, etc., where p is the beginning of the structure. On Windows, double (8 bytes) must start with an address that is a multiple of 8, so p + 8, p + 16, p + 24, etc.

0
source share

All Articles