alignas
-
hallo leute
folgender code:
struct alignas(32) basic_control { HWND handle = nullptr; txl::rect rect; const unsigned short id; protected: basic_control(unsigned short tid) noexcept : id(tid) { } }; /* class basic_control */ template<unsigned short ID> struct Control : public basic_control { Control(void) : basic_control(ID) { } }; struct Controls { Control<0x1000> btn1; Control<0x1001> btn2; Control<0x1002> btn3; Control<0x1003> btn4; }; ... Controls controls; int count = sizeof(controls) / sizeof(basic_control); basic_control *con = reinterpret_cast<basic_control*>(&controls); for(int i = 0; i < count; ++i) { con->rect.left = 12 + i; ++con; }
durch alignas(32) stelle ich sicher das ich immer eine 4 byte ausrichtung hab.
struct Controls sollte jetzt eigendlich im speicher gleich aufgebaut sein wie ein array.
ist es nun standardkonform das ich dann mittels einen pointer darauf zugreife als wenn es ein
echtes array waere ?Meep Meep
-
durch alignas(32) stelle ich sicher das ich immer eine 4 byte ausrichtung hab.
Eigentlich drückst du aus, dass du eine 32-Byte Ausrichtung wünschst.
struct Controls sollte jetzt eigendlich im speicher gleich aufgebaut sein wie ein array.
Das kann aber nicht mit Sicherheit gesagt werden. Zwar hat
Controls
möglicherweise Standardlayout (hängt vontxl::rect
ab), wodurch die Adresse des ersten Members stets der Adresse des vollständigen Objekts gleichen würde, Padding zwischen den Membern kann aber durchaus präsent sein. Lieber einpack
pragma reinhauen.ist es nun standardkonform das ich dann mittels einen pointer darauf zugreife als wenn es ein echtes array waere ?
Ohne Padding schon, da du die Zeiger lediglich inkrementierst, was gewissermaßen das aktuelle wording in [expr.add]/4 überlistet. Der eigentliche Knackpunkt liegt jedoch woanders:
[basic.compound]/3 schrieb:
If an object of type
T
is located at an addressA
, a pointer of type cvT*
whose value is the addressA
is said to point to that object, regardless of how the value was obtained. [ Note: For instance, the address one past the end of an array (5.7) would be considered to point to an unrelated object of the array’s element type that might be located at that address. There are further restrictions on pointers to objects with dynamic storage duration; see 3.7.4.3. — end note ]Dieser Paragraph wird nun durch P0137R0 abgeändert:
Every value of pointer type is one of the following:
- a pointer to an object or function (the pointer is said to point to the object or function), or
- a pointer past the end of an object (5.3.1 expr.unary.op), or
- the null pointer value (4.10 conv.ptr) for that type, or
- an invalid pointer value.
A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory (1.7 intro.memory) that the object occupies or the first byte in memory after the end of the storage occupied by the object, respectively . [ Note: A pointer past the end of an object (5.7) is not considered to point to an unrelated object of the object's type that might be located at that address. […] — end note]
Mit dem neuen Text hat dein Programm undefiniertes Verhalten;
++con
zeigt nicht auf das zweite Objekt, sondern ist ein dem ersten Objekt entsprechender past-the-end Zeiger.
-
Meep Meep schrieb:
ist es nun standardkonform das ich dann mittels einen pointer darauf zugreife als wenn es ein
echtes array waere ?Nein. Wenn du ein Array willst, dann mach ein Array...