kniffliges bitfield/union problem



  • Bitfelder gibt es aber nur bei struct. Bei einer union hättest du das Problem, dass immer nur eine Information zu einer Zeit gespeichert werden kann. Es ist nicht sicher gestellt dass die ersten 3 frei sind. Ausserdem sehe ich im Moment keinen Sinn in dem was du machen willst. Ich poste dir mal was zu unions und bitfields...

    9.5  Unions                                              [class.union]
    
    1 In a union, at most one of the data members can be active at any time,
      that is, the value of at most one of the data members can be stored in
      a union at any time.  The size of a union is sufficient to contain the
      largest of its data members.  Each data member is allocated as  if  it
      were  the  sole member of a struct.  A union can have member functions
      (including constructors and destructors), but not virtual (_class.vir-
      tual_) functions.  A union shall not have base classes.  A union shall
      not be used as a base class.  An object of a class with a  non-trivial
      default  constructor  (_class.ctor_),  a  non-trivial copy constructor
      (_class.copy_), a non-trivial destructor  (_class.dtor_),  or  a  non-
      trivial  copy assignment operator (_over.ass_, _class.copy_) cannot be
      a member of a union, nor can an array of such  objects.   If  a  union
      contains a static data member, or a member of reference type, the pro-
      gram is ill-formed.
    
    2 A union of the form
              union { member-specification } ;
      is called an anonymous union; it defines an unnamed object of  unnamed
      type.   The  member-specification  of  an  anonymous  union shall only
      define non-static data members.  [Note:  nested  types  and  functions
      cannot be declared within an anonymous union.  ] The names of the mem-
      bers of an anonymous union shall be distinct from  the  names  of  any
      other  entity  in  the scope in which the anonymous union is declared.
      For the purpose of name look up, after the anonymous union definition,
      the members of the anonymous union are considered to have been defined
      in the scope in which the anonymous union is declared.  [Example:
              void f()
              {
                  union { int a; char* p; };
                  a = 1;
                  // ...
                  p = "Jennifer";
                  // ...
              }
      Here a and p are used like ordinary (nonmember) variables,  but  since
      they are union members they have the same address.  ]
    
    3 Anonymous unions declared at namespace scope shall be declared static.
      Anonymous unions declared at block scope shall be  declared  with  any
      storage  class  allowed for a block-scope variable, or with no storage
      class.  A storage class is not allowed in a declaration of  an  anony-
      mous  union  in a class scope.  An anonymous union shall not have pri-
      vate or protected members (_class.access_).  An anonymous union  shall
      not have function members.
    
    4 A union for which objects or pointers are declared is not an anonymous
      union.  [Example:
    
              union { int aa; char* p; } obj, *ptr = &obj;
              aa = 1;       // error
              ptr->aa = 1;  // ok
      The assignment to plain aa is ill formed since the member name is  not
      visible  outside  the  union,  and  even if it were visible, it is not
      associated with any particular object.   ]  [Note:  Initialization  of
      unions   with   no   user-declared   constructors   is   described  in
      (_dcl.init.aggr_).  ]
    
      9.6  Bit-fields                                            [class.bit]
    
    1 A member-declarator of the form
              identifieropt : constant-expression
      specifies a bit-field; its length is set off from the  bit-field  name
      by  a  colon.   The bit-field attribute is not part of the type of the
      class member.  The constant-expression shall be an integral  constant-
      expression  with a value greater than or equal to zero.  The constant-
      expression may be larger than the number of bits in the object  repre-
      sentation  (_basic.types_)  of the bit-field's type; in such cases the
      extra bits are used as padding bits and  do  not  participate  in  the
      value  representation (_basic.types_) of the bit-field.  Allocation of
      bit-fields within a class object is implementation-defined.  Alignment
      of  bit-fields  is implementation-defined.  Bit-fields are packed into
      some addressable allocation unit.  [Note: bit-fields straddle  alloca-
      tion  units  on  some  machines  and  not  on  others.  Bit-fields are
      assigned right-to-left on some machines, left-to-right on others.  ]
    
    2 A declaration for a bit-field that omits the  identifier  declares  an
      unnamed  bit-field.   Unnamed bit-fields are not members and cannot be
      initialized.  [Note: an unnamed bit-field is  useful  for  padding  to
      conform  to  externally-imposed  layouts.   ]  As  a  special case, an
      unnamed bit-field with a width of zero specifies alignment of the next
      bit-field  at  an  allocation  unit  boundary.  Only when declaring an
      unnamed bit-field may the constant-expression  be  a  value  equal  to
      zero.
    
    3 A  bit-field  shall  not  be  a static member.  A bit-field shall have
      integral or enumeration type (_basic.fundamental_).  It is implementa-
      tion-defined  whether a plain (neither explicitly signed nor unsigned)
      char, short, int or long bit-field is  signed  or  unsigned.   A  bool
      value  can  successfully be stored in a bit-field of any nonzero size.
      The address-of operator & shall not be  applied  to  a  bit-field,  so
      there  are no pointers to bit-fields.  A non-const reference shall not
      be bound to a bit-field (_dcl.init.ref_).  [Note: if  the  initializer
      for  a  reference  of type const T& is an lvalue that refers to a bit-
      field, the reference is bound to a temporary initialized to  hold  the
      value  of  the  bit-field; the reference is not bound to the bit-field
      directly.  See _dcl.init.ref_.  ]
    
    4 If the value true or false is stored into a bit-field of type bool  of
      any  size (including a one bit bit-field), the original bool value and
      the value of the bit-field shall compare equal.  If the  value  of  an
      enumerator is stored into a bit-field of the same enumeration type and
      the number of bits in the bit-field is large enough to  hold  all  the
    
      values of that enumeration type, the original enumerator value and the
      value of the bit-field shall compare equal.  [Example:
              enum BOOL { f=0, t=1 };
              struct A {
                      BOOL b:1;
              };
              A a;
              void f() {
                      a.b = t;
                      if (a.b == t) // shall yield true
                      { /* ... */ }
              }
       --end example]
    

    [ Dieser Beitrag wurde am 26.05.2003 um 08:54 Uhr von MaSTaH editiert. ]



  • Bitfelder gibt es aber nur bei struct.
    stimmt. allerdings gibt auch unions innerhalb von structs.

    Bei einer union hättest du das Problem, dass immer nur eine Information zu einer Zeit gespeichert werden kann.
    das wäre kein problem, sondern das, was ich will 😉

    Ausserdem sehe ich im Moment keinen Sinn in dem was du machen willst.
    hardwareprogrammierung nennt sich das wohl 😉 und die betreffende hardware hat eben den speicher für verschiedene verwendungszwecke doppelt belegt.

    aber ok, es ist ja nun klar, dass es leider nicht geht.



  • Original erstellt von maximAL:
    **ok, ich hab folgendes bitfield:

    struct sSpriteAttribute1
    {
        vu16 PosX           :9;
        vu16 RotScaleIndex  :3;
        vu16 FlipHor        :1;
        vu16 FlipVer        :1;
        vu16 Size           :2;
    }__attribute__((packed));
    
    vu16 RotScaleIndex :5;
    
    vu16 :3; //3 leere bits
    vu16 FlipHor :1;
    vu16 FlipVer :1;
    ```**
    

    Du hast die Lösung doch schon! C++ unterstützt unnamed unions und structs. Also schreibst du:

    struct sSpriteAttribute1
    {
        vu16 PosX           :9;
        union {
            struct {
                vu16 RotScaleIndex  :5;
            }
            struct {
                vu16 :3;  //ob das tut weiss ich nicht, zur not vul6 tmp :3;
                vu16 FlipHor :1;
                vu16 FlipVer :1;
            }
        }
        vu16 Size           :2;
    }__attribute__((packed));
    


  • hmm, schade, geht wohl nicht. die bits liegen dann nicht mehr hintereinander, offensichtlich nimmt der compiler für die union immer 16bit 😞



  • Tipp: C++ ist eine oo-Sprache.

    Wenn es also wirklich darum geht kein bit zu verschwenden, egal, wieviel geschwindigkeit drauf geht (um etwas anderes kann es sich ja nicht handeln), da bastel doch ne Methode, wie get_FlipHor(), die das entsprechende Bit wieder gibt.



  • die eine hälfte der daten direkt holen, die andere über eine extra funktion? ne, also solche sauereien fang ich erst gar nicht an (was hat das auch mit OOP zu tun?)
    ich mach es ganz anders:
    ich erstell einmal die struct

    struct sSpriteAttribute1
    {
        vu16 PosX           :9;
        vu16                :3;
        vu16 FlipHor        :1;
        vu16 FlipVer        :1;
        vu16 Size           :2;
    }__attribute__((packed));
    

    und dann noch

    struct sSpriteAttribute1RotScale
    {
        vu16 PosX           :9;
        vu16 RotScaleIndex  :5;
        vu16 Size           :2;
    }__attribute__((packed));
    

    die kann ich dann je nach bedarf auf die entsprechende stelle im speicher zeigen lassen...

    [ Dieser Beitrag wurde am 26.05.2003 um 16:15 Uhr von maximAL editiert. ]



  • Original erstellt von maximAL:
    die eine hälfte der daten direkt holen, die andere über eine extra funktion? ne, also solche sauereien fang ich erst gar nicht an...

    Naja, Sauerei hin oder her (ich empfinde es eigentlich nicht als solche). Wenn du hardwarenah proggst und jedes Bit teuer ist wirst du wohl nicht drum herum kommen... Ne richtige Sauerei sind zwei anonyme structs (mit anonymen Variablen) in ner anonymen union in ner struct (@Peanut 😉 ).

    Original erstellt von maximAL:
    ...(was hat das auch mit OOP zu tun?)

    Nicht wirklich viel...

    [ Dieser Beitrag wurde am 26.05.2003 um 18:12 Uhr von MaSTaH editiert. ]



  • @maximAL: Guck dir mal die verschiedenen Operatoren an (<< >> & ^ | ! ~ usw.). Wenn du wirklich hardwarenah programmierst solltest du Bitmanipulationen, Shiften usw. auf jeden Fall drauf haben... 😉



  • keine angst, ich hab das drauf ( 😉 )
    ich hasse es nur wie die pest beim programmieren dauern in docs rumzuwühlen, weil ich wiedermal vergessen hab, auf welchem bit was ist. ausserdem wird der code mit sowas absolut unleserlich. es geht ja schliesslich auch so, wenn auch nicht so einfach, wie ichs gern hätte.



  • Original erstellt von maximAL:
    keine angst, ich hab das drauf ( 😉 )

    Na dann bin ich ja beruhigt 😃


Anmelden zum Antworten