Go: битовые поля и битовая упаковка - PullRequest
8 голосов
/ 26 апреля 2011

Битовые поля языка C предоставляют довольно удобный метод определения полей произвольной ширины в структуре (не обращайте внимания на проблемы с переносимостью в течение минуты.) Например, вот простая структура с парой полей и «флагом»:

#pragma pack(push,1)
struct my_chunk{

    unsigned short fieldA: 16;
    unsigned short fieldB: 15;
    unsigned short fieldC:  1;
};
#pragma pop()

Добавление операторов #pragma упаковывает эту структуру в 32-разрядное слово (обеспечивая выравнивание манипуляций с указателями my_chunk, например, наряду с экономией места).

Доступ к каждому полю синтаксически очень хорош:

struct my_chunk aChunk;
aChunk.fieldA = 3;
aChunk.fieldB = 2;
aChunk.fieldC = 1;

Альтернативный способ сделать это без помощи языка довольно уродлив и в значительной степени превращается в ассемблер. например Одно из решений состоит в том, чтобы иметь макрос сдвига для каждого поля, к которому вы хотите получить доступ:

#define FIELD_A  0xFF00
#define FIELD_B  0x00FE
#define FIELD_C  0x0001

#define get_field(p, v) ((*p)&f)
#define set_field(p, f, v) (*p) = (v<<f) + (*p)&(~f)

...
set_field(&my_chunk, FIELD_A, 12345);

.. или что-то в этом роде (для большей формальности взгляните на this )

Таким образом, вопрос в том, что если я хочу "делать" битовые поля в го, то как лучше всего это сделать?

Ответы [ 2 ]

9 голосов
/ 26 апреля 2011

"В Go нет текущих планов для битовых полей struct."

Вы можете написать пакет Go для этого; ассемблер не требуется.

7 голосов
/ 03 мая 2011

Если цель состоит в том, чтобы иметь очень маленькую структуру, вы, вероятно, просто сделаете:

package main

import "fmt"

type my_chunk uint32

func (c my_chunk) A() uint16 {
  return uint16((c & 0xffff0000) >> 16) 
}

func (c *my_chunk) SetA(a uint16) {
  v := uint32(*c)
  *c = my_chunk((v & 0xffff) | (uint32(a) << 16))
}

func main() {
  x := my_chunk(123)
  x.SetA(12)
  fmt.Println(x.A())
}

При текущем 6g / 8g вы смотрите на вызов функции с ~ 6 инструкциями для геттера, и со временем такие вызовы, вероятно, будут встроены.

...