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

What is the correct syntax to initialize bit-fields using C++11 "in-class initialization" feature?

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • I don't think its possible, at least I can not find a way to construct it with the c++ grammar summary. – PlasmaHH May 13 '13 at 11:33
  • 1
    They better fix this nonsense for C++14, unless there's a good reason why this should not be done. – Michael Goldshteyn Jun 11 '13 at 20:32
  • 1
    Was this fixed in c++14? – dshin Apr 15 '15 at 19:29
  • @dshin, Here is the [link to this issue](http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1341) from Ville Voutilainen's answer. But IMO, it is not fixed yet. – iammilind Apr 16 '15 at 04:30
  • The assignment is ambiguous, as amongst 8 bits, deciding which must be reset needs preexisting intuitive mathematical convention.. – Chawathe Vipul S Oct 16 '16 at 06:54
  • Possible duplicate of [Default values to bitfield elements](https://stackoverflow.com/questions/27057973/default-values-to-bitfield-elements/51533747). – Some Guy Jun 13 '20 at 09:50

5 Answers5

13

This was raised as Core Issue 1341 to the C++ standard, but was rejected by the C++ Core Working Group in October 2015 as NAD ("not a defect") - see http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1341

  • 2
    There's also recent work in this area, http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0187r1.pdf has been reviewed by EWG in Issaquah, and EWG gave direction to produce a new version of that proposal. – Ville Voutilainen Feb 07 '17 at 18:17
10

What is the correct syntax to initialize bit-fields using C++11 "in-class initialization" feature?

You cannot initialize bit-fields in-class. Paragraph 9.2 of the C++11 Standard specifies the grammar for class member declarators:

[...]

member-declarator:

declarator virt-specifier-seq(opt) pure-specifier(opt)

declarator brace-or-equal-initializer(opt)

identifier(opt) attribute-specifier-seq(opt): constant-expression

As you can see, declarators for bit-field members cannot be terminated by a brace-or-equal-initializer.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
2

You can write a constructor with initializer list to give default values to your bitfields.

struct bitfield {
  int i;
  int j : 8;

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

You can also create read-only fields with default values.

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) {};
};
Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
2

C++11 doesn't provide any syntax for default initializing bitfields, but C++ 20 does.

That means your example compiles fine when your C++ compiler supports C++20:

struct bitfield {
  int i = 0;      // ok
  int j : 8 = 0;  // ok since C++20
  int k : 8 {0};  // ditto
};

Note that you might need to explicitly enable C++20 support, e.g. with -std=c++20 when using a not too recent GCC/Clang version.

maxschlepzig
  • 35,645
  • 14
  • 145
  • 182
1

You cannot (in C++11) in-class initialize bitfields.

In MSVC and gcc (with extensions), the anonymous union and struct code lets you get around this a bit.

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

where we mix a fixed size raw with a union over bitfields, then in-class initialize the raw element.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524