This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-04-13


739. Signedness of plain bit-fields

Section: 11.4.10  [class.bit]     Status: CD3     Submitter: Mike Miller     Date: 3 November, 2008

[Moved to DR at the October, 2012 meeting.]

11.4.10 [class.bit] paragraph 3 says,

It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

The implications of this permission for an implementation that chooses to treat plain bit-fields as unsigned are not clear. Does this mean that the type of such a bit-field is adjusted to the unsigned variant or simply that sign-extension is not performed when the value is fetched? C99 is explicit in specifying the former (6.7.2 paragraph 5: “for bit-fields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int”), while C90 takes the latter approach (6.5.2.1: “Whether the high-order bit position of a (possibly qualified) 'plain' int bit-field is treated as a sign bit is implementation-defined”).

(See also issue 675 and issue 741.)

Additional note, May, 2009:

As an example of the implications of this question, consider the following declaration:

 struct S { int i: 2; signed int si: 2; unsigned int ui: 2; } s; 

Is it implementation-defined which expression, cond?s.i:s.si or cond?s.i:s.ui, is an lvalue (the lvalueness of the result depends on the second and third operands having the same type, per 7.6.16 [expr.cond] paragraph 4)?

Proposed resolution (August, 2011):

Change 11.4.10 [class.bit] paragraph 3 as follows:

A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (6.8.2 [basic.fundamental]). It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int, long, or long long bit-field is signed or unsigned.For a bit-field with a non-dependent type (13.8.3.2 [temp.dep.type]) that is specified to be plain (neither explicitly signed nor unsigned) short, int, long, or long long or a typename-name that is so defined (possibly through multiple levels of typedefs), it is implementation-defined whether the type of the bit-field is the corresponding signed or unsigned type. [Example:

 struct B { long x : 3; typedef signed int si; si y : 1; typedef int i; i z : 1; }; template<class T> struct A { T x : 7; };

It is implementation-defined whether B::x has type signed long or unsigned long. B::y has type signed int. It is implementation-defined whether B::z has type signed int or unsigned int. A<int>::x and A<signed int>::x designate the same entity of type signed int. A<unsigned int>::x has type unsigned int. —end example]

A bool value...

This resolution also resolves issue 675.

Note, January, 2012:

Additional questions have been raised about the proposed resolution, so the status was returned to "review" to allow further discussion.

Proposed resolution (February, 2012):

  1. Change 11.4.10 [class.bit] paragraph 3 as follows:

  2. A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (6.8.2 [basic.fundamental]). It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int, long, or long long bit-field is signed or unsigned. A bool value can successfully be stored...
  3. Add the following as a new section in C.7.7 [diff.class]:

  4. 11.4.10 [class.bit]

    Change: Bit-fields of type plain int are signed.

    Rationale: Leaving the choice of signedness to implementations could lead to inconsistent definitions of template specializations. For consistency, the implementation freedom was eliminated for non-dependent types, too.

    Effect on original feature: The choice is implementation-defined in C, but not so in C++.

    Difficulty of converting: Syntactic transformation.

    How widely used: Seldom.

This resolution also resolves issue 675.



close