1

MSVC++ gives me a compiler error when I try to initialize a bit field inside structure declaration:

struct SomeStruct
{
    bool a : 1 = false; // compiler error
    bool a = false : 1; // compiler error
} ;

What is the syntax for initializing bit fields inside structure declaration?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Serge Rogatch
  • 13,865
  • 7
  • 86
  • 158
  • Sorry, finally I came up with the right keywords to find the question already asked: [Bit-fields "In-class initialization" results in "error: lvalue required as left operand of assignment"](http://stackoverflow.com/questions/16520701/bit-fields-in-class-initialization-results-in-error-lvalue-required-as-left) – Serge Rogatch Sep 21 '15 at 09:36

2 Answers2

2

The error I get from clang is very telling:

bitfield member cannot have an in-class initializer

So you simply can't do it, you need a constructor that initializes the members.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks. MSVC++ rather complains about `;`. Actually, it's a known issue in C++11: http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1341 – Serge Rogatch Sep 21 '15 at 09:32
  • @SergeRogatch: "known" perhaps, but apparently not garnering any interest :-( – Kerrek SB Sep 21 '15 at 09:34
  • 1
    Although clang tends to be more conformant it does have bugs too and there are cases where clang is incorrect. I have filed several clang, gcc and Visual Studio bugs based on SO questions before. – Shafik Yaghmour Sep 21 '15 at 09:40
1

I am a bit surprised but apparently Visual Studio is correct here, if we look at the grammar from section 9.2 of the draft C++11 standard it says:

member-declarator:
  declarator virt-specifier-seqopt pure-specifieropt
  declarator brace-or-equal-initializeropt
  identifieropt attribute-specifier-seqopt: constant-expression

and bit-fields are not allowed to have a brace-or-equal-initializer. It is not clear to me why this restriction exists though. This feels like the first time I realized a in-class initializer makes a class a non-aggregate.

This apparently is a defect:

The grammar for member-declarator (9.2 [class.mem]) does not, but should, allow for a brace-or-equal-initializer on a bit-field declarator.

This issue was apparently also caught before C++11 was finalized as we can see from Issues Found Implementing C++0x:

  1. (Richard Smith) class.mem: bitfield members cannot have in-class initializers

The grammar does not allow a brace-or-equal-initializer for a bitfield member. This seems like an oversight. A brace-or-equal-initializer after a constant- expression appears to be unambiguous.

clang behavior: clang implements the letter of the standard.

suggested resolution: Change the grammar as follows:

member-declarator:
    identifieropt attribute-specifier-seqopt : constant-expression brace-or-equal-initializeropt

but apparently this feel through the cracks.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740