Битовые поля Инициализация в классе приводит к ошибке: lvalue требуется как левый операнд присваивания

struct bitfield {
  int i = 0;  // ok
  int j : 8 = 0;  // error: lvalue required as left operand of assignment
};

Каков правильный синтаксис для инициализации битовых полей с использованием функции «инициализации в классе» С++ 11?


person iammilind    schedule 13.05.2013    source источник
comment
Я не думаю, что это возможно, по крайней мере, я не могу найти способ построить его с помощью сводки грамматики С++.   -  person PlasmaHH    schedule 13.05.2013
comment
Лучше бы они исправили эту ерунду для C++14, если только нет веских причин, по которым этого делать не следует.   -  person Michael Goldshteyn    schedule 12.06.2013
comment
Это было исправлено в С++ 14?   -  person dshin    schedule 15.04.2015
comment
@dshin, вот ссылка на эту проблему из ответа Вилле Вутилайнена. Но имхо, это еще не исправлено.   -  person iammilind    schedule 16.04.2015
comment
Назначение неоднозначно, так как среди 8 бит решение, которое должно быть сброшено, требует ранее существовавшего интуитивного математического соглашения.   -  person Chawathe Vipul S    schedule 16.10.2016
comment
Возможный дубликат значений по умолчанию для элементов битового поля.   -  person Some Guy    schedule 13.06.2020


Ответы (4)


Каков правильный синтаксис для инициализации битовых полей с использованием функции «инициализации в классе» С++ 11?

Вы не можете инициализировать битовые поля в классе. Параграф 9.2 стандарта С++ 11 определяет грамматику для деклараторов членов класса:

[...]

член-декларатор:

декларатор virt-specifier-seq(opt) pure-specifier(opt)

объявитель скобок-или-равно-инициализатор(опция)

идентификатор(opt) атрибут-specifier-seq(opt): константное-выражение

Как вы можете видеть, деклараторы для членов битового поля не могут быть завершены скобкой-или-равным-инициализатором.

person Andy Prowl    schedule 13.05.2013
comment
Что стоит за этим? - person Litherum; 26.12.2014
comment
@Литерум: я не знаю. Возможно оплошность? - person Andy Prowl; 26.12.2014

Это было поднято как основная проблема 1341 стандарта C++, но было отклонено основной рабочей группой C++ в октябре 2015 года как NAD («не является дефектом») — см. http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1341

person Ville Voutilainen    schedule 15.05.2014
comment
В этой области также есть недавняя работа, open-std. org/JTC1/SC22/WG21/docs/papers/2016/p0187r1.pdf был рассмотрен EWG в Иссакуа, и EWG дала указание подготовить новую версию этого предложения. - person Ville Voutilainen; 07.02.2017

Вы не можете (в С++ 11) инициализировать битовые поля в классе.

В MSVC и gcc (с расширениями) анонимный код union и struct позволяет немного обойти это.

struct bitfield {
  int i = 0;  // ok
  union {
    uint32_t raw = 0;
    struct {
      int j : 8;
      int x : 3;
    };
  };
};

где мы смешиваем фиксированный размер raw с union над битовыми полями, затем в классе инициализируем элемент raw.

person Yakk - Adam Nevraumont    schedule 15.05.2014

Вы можете написать конструктор со списком инициализаторов, чтобы задать значения по умолчанию для ваших битовых полей.

struct bitfield {
  int i;
  int j : 8;

  bitfield() : i(0), j(0) {};
};

Вы также можете создать поля только для чтения со значениями по умолчанию.

struct _UserRegister1
{
  uint8_t _RES0 : 1;
  const uint8_t reserved1 : 1;
  uint8_t _HTRE : 1;
  const uint8_t reserved2 : 3;
  uint8_t _VDDS : 1;
  uint8_t _RES1 : 1;

  _UserRegister1() : reserved1(1), reserved2(7) {};
};
person Bence Kaulics    schedule 26.08.2017