vector von eigener Struktur - Linear im Speicher?





  • Ja Moment, was nicht gesichert ist, ist, dass m[0] des zweiten Objektes direkt auf m[11] des ersten folgt (Stichwort Padding, und wenn da eine vtable drin ist, fliegt dir das ganz auseinander).

    Wenn es sich um POD handelt, befrag mal die Dokumentation deines Compilers nach packed structures. Gcc benutzt __attribute__((__packed__)), MSVC hat, wenn ich das richtig im Kopf habe, ein Pragma dafür. Wenn das Ding Laufzeitpolymorphie betreibt, wird dein Vorhaben so nicht funktionieren.



  • Cool, danke!

    Endlich eine Nachtlektüre 😋

    seldon:
    vtable gibt's doch nur, wenn ich virtual functions habe, oder? und dann ist sizeof(Matrix) ja auch != sizeof(12 * float), oder? Deswegen hatte ich ja diesen Zusatz drin, meine Matrix ist daher bewusst nicht vererbbar gemacht. Laufzeitpolymorphie für nicht-virtuelle Klassen? Und ich hab jetzt keine Ahnung von Alignment, aber wenn ich Vielfache von 4 Bytes habe, ist das dann nicht irgendwie ausgeschlossen? 😕

    #pragma pack(show) sagt 8. sizeof(float) * 12 ist ein Vielfaches von 8. Bin ich damit aus dem Schneider? Und wie kann ich das compilerübergreifend korrekt programmieren?



  • Ohne virtuelle Funktionen gibt's keine vtable, das ist richtig. Padding kann es aber trotzdem noch geben - wenn sizeof(Matrix) == sizeof(float * 12) ist, ist das bei dir wohl nicht der Fall, aber ich würde das mindestens irgendwo in den Testcases prüfen.

    Was du da betreibst, wird in der Praxis womöglich funktionieren, Garantien dafür sind aber schwer aufzutreiben. Wenn du diesen Weg gehen willst, wäre es sinnvoll, sich ein paar Compilezeitprüfungen für Voraussetzungen zu basteln. Etwa

    template<std::size_t N1, std::size_t N2> struct assert_equal_size         { };
    template<std::size_t N1>                 struct assert_equal_size<N1, N1> { typedef int type; };
    
    typedef assert_equal_size<sizeof(float) * 12, sizeof(Matrix)>::type matrix_layout_is_alright_t;
    


  • Genial, musste drei Mal hinschauen, um das zu verstehen.

    Und... jetzt ganz doofe Frage... wie nutz ich das dann? #ifdef ist ja nur für den Präprozessor, passt also nicht. Oder soll ich einfach irgendwo, wo ich die Matrix nutze, "matrix_layout_is_alright_t;" schreiben, weil das im Falle der Nichtdefinition einen "ist nicht definiert"-Fehler ergibt? Schön wär ja, wenn ich das wirklich mit einem assert verbinden könnte.



  • Solche Compile Time Assertions wurden von Alexandrescu eingeführt. Du kannst dafür Boost StaticAssert benutzen, einen Compiler, der dieses C++0x-Feature schon unterstützt (z. B. VS 2010 oder gcc) oder schnell selbst schreiben (dafür sind die Fehlermeldungen nicht so schön):

    template<bool>
    struct static_assert;
    
    template<>
    struct static_assert<true> {};
    
    class Matrix
    {
    	float foo[12];
    };
    
    static_assert<sizeof(Matrix) == 12 * sizeof(float)> static_assert_no_padding_in_class_matrix;
    

    Edit: Es wird sogar schon im Forum gehighlightet 😃



  • Ich will einen Herzsmiley, mehr wollte ich nämlich nicht schreiben.

    Danke 🙂



  • seldon schrieb:

    Ohne virtuelle Funktionen gibt's keine vtable, das ist richtig. Padding kann es aber trotzdem noch geben - wenn sizeof(Matrix) == sizeof(float * 12) ist, ist das bei dir wohl nicht der Fall, aber ich würde das mindestens irgendwo in den Testcases prüfen.

    Was du da betreibst, wird in der Praxis womöglich funktionieren, Garantien dafür sind aber schwer aufzutreiben. Wenn du diesen Weg gehen willst, wäre es sinnvoll, sich ein paar Compilezeitprüfungen für Voraussetzungen zu basteln. Etwa

    template<std::size_t N1, std::size_t N2> struct assert_equal_size         { };
    template<std::size_t N1>                 struct assert_equal_size<N1, N1> { typedef int type; };
    
    typedef assert_equal_size<sizeof(float) * 12, sizeof(Matrix)>::type matrix_layout_is_alright_t;
    

    Ok, ich habs gerade ausprobiert und es geht 😉 Was mich interessiert ist wieso. Ich ruf doch das assert_equal_size immer mit zwei parametern auf. Wie macht er die Unterscheidung zwischen zwei gleichen parametern wie z.B. <8, 8> und <7, 8>? wieso nimmt er bei einem template "aufruf" mit zwei paramtern (aber den gleichen) das template mit nur einem parameter?!



  • Wenn zwei Templates gleich gut passen, wird das spezialisiertere genommen.



  • Wenn eins davon spezialisierter ist, dann passen sie ja nimmer gleich gut 😃

    BTW @Eisflamme: lies mal in Standard bezüglich "standard layout class" nach (unter "9 Classes").
    Halte die Bedingungen für eine "standard layout class" ein, und es ist garantiert dass deine Matrix so im Speicher liegt wie du es brauchst.



  • hustbaer schrieb:

    Wenn eins davon spezialisierter ist, dann passen sie ja nimmer gleich gut 😃

    :p


Anmelden zum Antworten