9 Şubat 2018 Cuma

bitfield alanlar

Giriş
bitfield alanlar struct ve union içinde tanımlanabilir.
Örnek
Şöyle yaparız.
struct bitfield {
  int i = 0;
  int j : 8;
};
Örnek
Şöyle yaparız.
union {
  uint32_t cw          : 13;
  struct {
    uint32_t setting4  : 4;
    uint32_t cmd       : 9;
  };
} control;
Örnek
Bit field alanlar için unsigned alan kullanmak daha iyi. Şu kod unsigend alan olmadığı için hatalı çıktı verir.
#include <stdio.h>

struct mystruct { int enabled:1; };
int main()
{
  struct mystruct s;
  s.enabled = 1;
  if(s.enabled == 1)
    printf("Is enabled\n"); // --> we think this to be printed
  else
    printf("Is disabled !!\n");
}

İlklendirme
Bitfield alanlara ilk değerlerini şöyle atayamıyoruz.
struct bitfield {
  int i = 0;  // ok
  int j : 8 = 0;  // error: lvalue required as left operand of assignment
};
Biraz hile yaparak şöyle yapabiliriz
struct bitfield {
  int i = 0;  // ok
  union {
    uint32_t raw = 0;
    struct {
      int j : 8;
      int x : 3;
    };
  };
};
Portable Kod
bitfield alanlar portable kod için kullanılamaz deniliyor. Açıklaması şöyle.
Bitfield's actual memory layout is implementation defined: if the memory layout must follow a precise specification, bitfields should not be used and hand-coded bit manipulations may be required.
Alanların adresi
Btifield alanların adresi alınamaz. Açıklaması şöyle.
The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields.
Örnek
Derleme hatasın görmek için şöyle yaparız.
struct bitField {
    uint8_t n0 : 1;
    uint8_t n1 : 1;
    uint8_t n2 : 1;
    uint8_t n3 : 1;
    uint8_t n4 : 1;
    uint8_t n5 : 1;
    uint8_t n6 : 1;
    uint8_t n7 : 1;
};

int main() {
    bitField example;

    // Can address the whole struct
    std::cout << &example << '\n'; // FINE, addresses a byte

    // Can not address for example n4 directly
    std::cout << &example.n4; // ERROR, Can not address a bit

    // Printing it's value is fine though
    std::cout << example.n4 << '\n'; // FINE, not getting address

    return 0;
}





Hiç yorum yok:

Yorum Gönder