Design für vector-Klasse gesucht



  • asfdlol schrieb:

    sie hat noch einen: undefined behaviour.

    Wo genau?



  • Meine einfachen Matrix-/Vektorklassen nutzten nie Vererbung. Halte ich auch nicht fuer richtig. Zu Speicherlayout? Da gibt es vielleicht Unterschiede in Debug und Release.

    sie hat noch einen: undefined behaviour.

    Nun, normalerweise kann man von einen Union nur ueber den Member wieder lesen, ueber den man reingeschrieben hat. Die meisten Compiler verhalten sich trotzdem wie erwartet, wenn Arrayelemente auf Member gemappet werden, wenn das Speicherlayout gleich ist. Jedoch besitzen hier Scalar[3] und struct ... x,y,z,w nicht das gleiche Speicherlayout, was zu Problemen fuehren kann.

    Elemente auch über ihren Namen ansprechen zu können.

    Ich verzichte darauf, weils eben nicht noetig ist und du dir bei Bedarf einfach Zugriffsfunktionen schreiben kannst. Aus vec.x wird dann eben vec.x() .



  • Singender Holzkübel schrieb:

    asfdlol schrieb:

    sie hat noch einen: undefined behaviour.

    Wo genau?

    1. wenn man in einen member einer union schreibt darf man von den anderen nicht lesen. das erlaubt deine implementierung aber.
    2. ich bin mir nicht sicher ob das pod-struct und das array plattformunabhängig konsistent gemappt werden, bzw. weiss ich nicht ob es definiert ist vom standard.

    edit:

    knivil schrieb:

    Meine einfachen Matrix-/Vektorklassen nutzten nie Vererbung. Halte ich auch nicht fuer richtig. Zu Speicherlayout? Da gibt es vielleicht Unterschiede in Debug und Release.

    mit speicherlayout ist vermutlich gemeint, dass es bei gewissen apis vorteilhaft ist wenn die komponenten eines vektors fortlaufend gespeichert sind.

    edit 2:

    knivil schrieb:

    Elemente auch über ihren Namen ansprechen zu können.

    Ich verzichte darauf, weils eben nicht noetig ist und du dir bei Bedarf einfach Zugriffsfunktionen schreiben kannst. Aus vec.x wird dann eben vec.x() .

    👍 sehe ich genau so.



  • mit speicherlayout ist vermutlich gemeint, dass es bei gewissen apis vorteilhaft ist wenn die komponenten eines vektors fortlaufend gespeichert sind.

    Ich weiss.



  • asfdlol schrieb:

    1. wenn man in einen member einer union schreibt darf man von den anderen nicht lesen. das erlaubt deine implementierung aber.
    2. ich bin mir nicht sicher ob das pod-struct und das array plattformunabhängig konsistent gemappt werden, bzw. weiss ich nicht ob es definiert ist vom standard.

    Stimmt du hast recht, daran habe ich nicht gedacht.
    Original Post edited.


  • Mod

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.



  • rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.


  • Mod

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.



  • rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private


  • Mod

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.



  • rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.

    das stimmt in meinen augen für vererbung nicht:

    N1905 §10.0.4 schrieb:

    The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [Note: a
    derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means
    “directly derived from.” A DAG of subobjects is often referred to as a “subobject lattice.”
    Base

    Derived1

    Derived2
    5 The arrows need not have a physical representation in memory. — end note ]


  • Mod

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.

    das stimmt in meinen augen für vererbung nicht:

    N1905 §10.0.4 schrieb:

    The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [Note: a
    derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means
    “directly derived from.” A DAG of subobjects is often referred to as a “subobject lattice.”
    Base

    Derived1

    Derived2
    5 The arrows need not have a physical representation in memory. — end note ]

    das ist aber ein POD fuers layout.

    A type that is standard-layout means that it orders and packs its members in a way that is compatible with C. A class or struct is standard-layout, by definition, provided:
    It has no virtual functions
    It has no virtual base classes
    All its non-static data members have the same access control (public, private, protected)
    All its non-static data members, including any in its base classes, are in the same one class in the hierarchy
    The above rules also apply to all the base classes and to all non-static data members in the class hierarchy
    It has no base classes of the same type as the first defined non-static data member

    A class/struct/union is considered POD if it is trivial, standard-layout, and all of its non-static data members and base classes are PODs.



  • rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.

    das stimmt in meinen augen für vererbung nicht:

    N1905 §10.0.4 schrieb:

    The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [Note: a
    derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means
    “directly derived from.” A DAG of subobjects is often referred to as a “subobject lattice.”
    Base

    Derived1

    Derived2
    5 The arrows need not have a physical representation in memory. — end note ]

    das ist aber ein POD fuers layout.

    A type that is standard-layout means that it orders and packs its members in a way that is compatible with C. A class or struct is standard-layout, by definition, provided:
    It has no virtual functions
    It has no virtual base classes
    All its non-static data members have the same access control (public, private, protected)
    All its non-static data members, including any in its base classes, are in the same one class in the hierarchy
    The above rules also apply to all the base classes and to all non-static data members in the class hierarchy
    It has no base classes of the same type as the first defined non-static data member

    A class/struct/union is considered POD if it is trivial, standard-layout, and all of its non-static data members and base classes are PODs.

    der von mir gequotete paragraph schliesst layout-pods nicht aus und deiner macht keine aussage bezüglich der anordnung - von im beispiel x, y, z und w - in der most-derived-class.


  • Mod

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.

    das stimmt in meinen augen für vererbung nicht:

    N1905 §10.0.4 schrieb:

    The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [Note: a
    derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means
    “directly derived from.” A DAG of subobjects is often referred to as a “subobject lattice.”
    Base

    Derived1

    Derived2
    5 The arrows need not have a physical representation in memory. — end note ]

    das ist aber ein POD fuers layout.

    A type that is standard-layout means that it orders and packs its members in a way that is compatible with C. A class or struct is standard-layout, by definition, provided:
    It has no virtual functions
    It has no virtual base classes
    All its non-static data members have the same access control (public, private, protected)
    All its non-static data members, including any in its base classes, are in the same one class in the hierarchy
    The above rules also apply to all the base classes and to all non-static data members in the class hierarchy
    It has no base classes of the same type as the first defined non-static data member

    A class/struct/union is considered POD if it is trivial, standard-layout, and all of its non-static data members and base classes are PODs.

    der von mir gequotete paragraph schliesst layout-pods nicht aus und deiner macht keine aussage bezüglich der anordnung - von im beispiel x, y, z und w - in der most-derived-class.

    steht da, es ist C order.

    In c werden alle memeber der deklarationsreihenfolge nach angeordnet.

    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.



  • rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    asfdlol schrieb:

    rapso schrieb:

    otze schrieb:

    @rapso ist unter den Bedingungen überhaupt noch sichergestellt, dass das speicherlayout der vektoren irgendwas ist, womit die Grafikkarte klar kommt? Also dass die elemente kontinuirlich im Sepicher liegen und kein padding etc drin vorkommt?

    solange du da nicht explizit alignment/padding dranbaust, werden die klassen wie erwartet im speicher liegen. auch auf gpus (falls du gerade cuda meinst) wuerde es richtig laufen.

    das dürfte für non-pod-types (wie deiner einer ist) implementation-defined sein.

    ich seh nicht wo etwas nicht POD sein soll.

    ist nicht pod, da:
    1. vererbung
    2. member in private

    fuers layouten der klassen sind es PODs, es gibt keine member oder sonst etwas was ein alignment bzw. padding enforcen wuerde auf nachfolgende elemente.
    solange du nicht per hand eingreifst ist das layout wohl definiert und wird von jedem c++ compiler gleich umgesetzt.

    das stimmt in meinen augen für vererbung nicht:

    N1905 §10.0.4 schrieb:

    The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. [Note: a
    derived class and its base class subobjects can be represented by a directed acyclic graph (DAG) where an arrow means
    “directly derived from.” A DAG of subobjects is often referred to as a “subobject lattice.”
    Base

    Derived1

    Derived2
    5 The arrows need not have a physical representation in memory. — end note ]

    das ist aber ein POD fuers layout.

    A type that is standard-layout means that it orders and packs its members in a way that is compatible with C. A class or struct is standard-layout, by definition, provided:
    It has no virtual functions
    It has no virtual base classes
    All its non-static data members have the same access control (public, private, protected)
    All its non-static data members, including any in its base classes, are in the same one class in the hierarchy
    The above rules also apply to all the base classes and to all non-static data members in the class hierarchy
    It has no base classes of the same type as the first defined non-static data member

    A class/struct/union is considered POD if it is trivial, standard-layout, and all of its non-static data members and base classes are PODs.

    der von mir gequotete paragraph schliesst layout-pods nicht aus und deiner macht keine aussage bezüglich der anordnung - von im beispiel x, y, z und w - in der most-derived-class.

    steht da, es ist C order.

    In c werden alle memeber der deklarationsreihenfolge nach angeordnet.

    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

    da steht dass es mit der art wie es in C gemacht wird kompatibel ist. daraus einen schluss für vererbung zu folgern halte ich für übermütig da es in c natürlich keine vererbung gab.



  • Quote war 4tw! 🙂



  • rapso schrieb:

    [...]
    All its non-static data members, including any in its base classes, are in the same one class in the hierarchy
    [..]

    betrachten wir den Code nochmal genauer:

    //Klassen wie Vector2D, Vector3D, Vector4D
    class Vector2D_
    {
      float x,y;
    public:
     float& At(size_t Idx){return Idx==1?y:x;}
    };
    class Vector3D_ : public Vector2D_
    {
     float z;
    public:
     float& At(size_t Idx){return Idx==2?z:Vector2D_::At(Idx);}
    };
    

    trifft das hier zu? z ist in einer anderen klasse als x und y. oder leg ich den Teil gerade falsch aus?



  • Der C++ Standard garantiert im Fall eines standard layout struct zwar, dass die Member in Deklarationsreihenfolge im Speicher liegen, das ist aber nicht hinreichend für lineares Layout der Member. Zumindest afaik gibt es, von Arrays abgesehen, keinen standardkonformen Weg, dies sicherzustellen. Falls jemand tatsächlich einen standardkonformen Weg kennt, so wäre ich ebenfalls sehr daran interessiert, suche seit Jahren nach einer Lösung für das Problem...



  • @dot
    Geht's dir hier um das sog. "structure packing"? Also dass bei

    struct foo { char c; int i; };
    

    üblicherweise sizeof(int) - 1 Bytes zwischen c und i freigelassen werden?

    Vielleicht sollte man dazu einfach das #pragma pack von MSVC standardisieren.



  • hustbaer schrieb:

    @dot
    Geht's dir hier um das sog. "structure packing"? Also dass bei

    struct foo { char c; int i; };
    

    üblicherweise sizeof(int) - 1 Bytes zwischen c und i freigelassen werden?

    Mir geht es vor allem darum, dass der Standard keine Garanie bietet. Dass es unter allen möglichen Compilern natürlich trotzdem funktionieren wird, ist eine andere Geschichte...

    hustbaer schrieb:

    Vielleicht sollte man dazu einfach das #pragma pack von MSVC standardisieren.

    Zumindest afaik unterstützten die wenigsten Architekturen unaligned Memory Access, x86 is da eher eine Ausnahme als die Regel und selbst unter x86 geht das nur bedingt. Und bereits unter x86/MSVC bedeutet #pragma pack potentiell weniger effizienter Code. Das zu standardisieren, halte ich für sehr problematisch. Selbst wenn man den Compiler Code generieren ließe, der die einzelnen Bytes aus größeren Blöcken abschält, wird man z.B. im Zusammenhang mit Concurrency dann wohl auf Probleme ähnlich zu denen mit Bitfeldern stoßen. Und selbst wenn wir so etwas wie #pragma pack hätten, haben wir unser eigentliches Problem (wir wüden gerne per Name und per Index zugreifen) noch nicht gelöst...

    Wenn du mich fragst, wäre es sinnvoller, einfach im Standard zu garantieren, dass aufeinanderfolgende struct Member von gleichem Typ per union auf ein Array aliasen dürfen und umgekehrt. Es gibt ja bereits in C++11 die Sache mit standard layout unions von standard layout structs mit einer common initial sequence. Die ist nur leider für unseren Fall hier noch nicht ausreichend...


Anmelden zum Antworten