I want to construct an object of class T
by using ::operator new(size_t)
and placement new
.
To "extend" the size of char v[1]
, which is the last declared data member in T
, I allocate sizeof(T) + n - 1
bytes with operator new()
, where n
is the wanted size in bytes. This trick allows me to access v[i]
for any i
in [0, n -1]
.
My questions are about the C++ standard:
Does 开发者_如何学Pythonthe order of declaration of data members in
T
reflect the order in which data is represented in memory?If the order is preserved, are data member alignments also preserved no matter how bigger is the size of the allocated memory?
1) Yes. From the section on pointer comparisons, the standard states that pointers to later members must compare as greater than pointers to earlier members. Edit: As pointed out by Martin, the standard only mandates this for POD structs.
2) Yes. Data alignment is not affected by the size of the allocation.
The thing is, nothing in the standard actually guarantees that the trick of using arrays this way works (IIRC).
struct something {
...
char buf[1];
};
However, this is done so commonly that it is a de-facto standard. The standards folks, last time I checked, were working on a way that they could codify these existing practices (It's already made its way into the C standard and it's only a matter of time before it's standardized in C++).
1a: Yes, just like C, the order of data members define the order in memory.
1b: Not unless the class is a POD (plain-old-data) class. To get that, it must not have constructors or virtual functions. The C++ standard has a list of rules that define what qualifies as POD.
You can influence the alignment in memory with the pragma pack declarations, just Google for it.
Does the order of declaration of data members in T reflect the order in which data is represented in memory?
In limited situations yes.
See Section 9 Classes [class] paragraph 7 (Look for details about A standard-layout class)
But in general no. There are no guarantees about the order of members in different protected/private/public regions.
If the order is preserved, are data member alignments also preserved no matter how bigger is the size of the allocated memory?
What do you mean preserved. The compiler decides for you. Once they are defined for a class they are constant through the code.
I want to construct an object of class T by using ::operator new(size_t) and placement new.
This is guaranteed. As long as you use new to allocate a block of memory at lease the same size as T then it is guaranteed to be aligned correctly for objects of type T.
3.1.1 Alignment [basic.align]
Paragraph 5:
Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
Thus if you have an object that is aligned to stricter requirement it is guaranteed to be aligned for weaker alignments. Thus space aligned for something that that is larger than T is also aligned for objects of size T.
5.3.4 New [expr.new]
Paragraph 10
A new-expression passes the amount of space requested to the allocation function as the first argument of type std::size_t. That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array. For arrays of char and unsigned char, the difference between the result of the new-expression and the address returned by the allocation function shall be an integral multiple of the strictest fundamental alignment requirement (3.11) of any object type whose size is no greater than the size of the array being created. [ Note: Because allocation functions are assumed to return pointers to storage that is appropriately aligned for objects of any type with fundamental alignment, this constraint on array allocation overhead permits the common idiom of allocating character arrays into which objects of other types will later be placed. — end note ]
精彩评论