[C++] constexpr + explizites Padding

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[C++] constexpr + explizites Padding

Beitrag von Krishty »

Ich definiere Padding quasi immer selber, wenn ich andere Bibliotheken einbinde. Bei mir wird etwa

  struct Foo {
    int a;
    void * b;
  };


zu

  #if COMPILED_FOR_X64
    #define PAD_4B_ON_X64 int : 32 // vier anonyme Bytes
  #else
    #define PAD_4B_ON_X64 // tut nix
  #endif

  struct Foo {
    int a;
    PAD_4B_ON_X64;
    void * b;
  };


… und das hat nun lange sehr gut funktioniert, aber mit constexpr geht das leider in die Brüche: Während Visual C++ die anonymen Daten praktischerweise ignoriert, will Clang sie initialisiert haben:

  constexpr Foo f = { 1, 2 }; // Fehler: initialisiert a und das Padding; lässt b uninitialisiert

Tja. Weiß zufällig jemand von euch, ob ich darauf hoffen kann, dass Clang die Member irgendwann ignoriert, oder ist das im Standard schlicht nicht definiert?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] constexpr + explizites Padding

Beitrag von dot »

constexpr Foo f = { 1, nullptr }; funktioniert laut godbolt sowohl mit msvc als auch mit clang und gcc; imo ist das alles wohldefiniert:
  • Aggregate Initialization mit einer Initializer-List der Länge n initialisiert laut Standard die ersten n Member. [dcl.init.aggr § 3.2]
  • Unnamed Bitfields sind keine Member. [class.bit § 2]
Es sei aber darauf hingewiesen dass die Art und Weise wie Bitfields in einem Objekt allokiert und ausgerichted sind implementation-defined ist. Und meiner aktuellen Auffassung nach darf der Compiler ein unnamed Bitfield theoretisch absolut irgendwohin packen; imo gibt es nichtmal eine Garantie dass das Bitfield zwischen den beiden Membern liegen muss zwischen denen es deklariert wurde. Ich würde mir ernsthaft die Frage stellen, inwiefern du im Zeitalter von alignas() wirklich manuell Padding definieren willst...
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] constexpr + explizites Padding

Beitrag von Krishty »

dot hat geschrieben:constexpr Foo f = { 1, nullptr }; funktioniert laut godbolt sowohl mit msvc als auch mit clang und gcc; imo ist das alles wohldefiniert
Bei mir nicht: https://godbolt.org/g/rkSyRj
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [C++] constexpr + explizites Padding

Beitrag von dot »

Oh, ich hab's mit einer globalen Variable versucht, dort hat's geklappt. Ich würde jetzt mal soweit gehen, zu postulieren, dass das ein Bug in Clang ist...
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] constexpr + explizites Padding

Beitrag von Krishty »

Scheiße, du hast recht! Ja, dann ist es ein Bug. Sowas habe ich ja mittlerweile im Urin …

In meinem Produktions-Code *ist* es eine globale Variable, aber es funktioniert trotzdem nicht. Wahrscheinlich, weil die Version hoffnungslos veraltet ist. Danke, dass du’s nochmal anders getestet hast als ich!

P.S.: Zum Warum: Ich kompiliere meinen Kram ohne Padding, und da sind immer wieder API-Fetzen zwischen, die es brauchen. Zum einen mag ich struct-Padding schlicht nicht, weil es implizit/unsichtbar ist und deshalb schwer nachvollziehbar (es gibt ja eine halbe Million Threads à Hilfe! Warum ist mein struct 16 B groß obwohl ich 9 erwartet hätte?! da draußen). Zum anderen kotzt mich die Compiler-abhängige Syntax an (obwohl sich #pragma pack langsam durchzusetzen scheint; zumindest VC/Clang/GCC können’s).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten