Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signed bit field in C++14

I believe that until C++14 a bit field of a struct declared as int was still interpreted as either signed or unsigned, the interpretation being implementation defined. Reference: http://en.cppreference.com/w/cpp/language/bit_field.

Is this still the case in C++14? I.e., is the code below guaranteed to work as inteded?

#include <iostream>

struct X
{
    int f:3;
};

int main() 
{
    X x;
    x.f = -2; // is this going to be indeed signed? It seems so.
    std::cout << x.f << std::endl; // displays -2
}
like image 400
vsoftco Avatar asked Nov 15 '15 18:11

vsoftco


People also ask

What is bit field in C++?

A bit field can be any integral type or enumeration type. End of C++ only. The maximum bit-field length is 64 bits. To increase portability, do not use bit fields greater than 32 bits in size.

Does C support bit fields?

In C and C++, native implementation-defined bit fields can be created using unsigned int , signed int , or (in C99) _Bool . In this case, the programmer can declare a structure for a bit field which labels and determines the width of several subfields.

What is bit field explain with example?

In programming terminology, a bit field is a data structure that allows the programmer to allocate memory to structures and unions in bits in order to utilize computer memory in an efficient manner. Since structures and unions are user-defined data types in C, the user has an idea of how much memory will they occupy.


1 Answers

According to C++11 standard §9.6/p3 Bit-fields [class.bit] (Emphasis Mine):

A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (3.9.1). 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 in a bit-field of any nonzero size. The address-of operator & shall not be applied to a bit-field, so there are no pointers to bitfields. A non-const reference shall not be bound to a bit-field (8.5.3). [ Note: If the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly. See 8.5.3. —end note ]

So you're correct for the first part. Indeed until C++14 a bit field of a struct declared as signed was still interpreted as either signed or unsigned, the interpretation being implementation defined.

As already mentioned in this comments by @T.C. Defect reports referring to the issue were made DR739, DR675. Resulting in the following resolutions in C++14 standard:

The wording "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.", was removed, and the C++14 wording now is:

A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (3.9.1). A bool value can successfully be stored in a bit-field of any nonzero size. The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields. A non-const reference shall not be bound to a bit-field (8.5.3). [ Note: If the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly. See 8.5.3. —end note ]

Also in §C.1.8 Clause 9: classes [diff.class] the following section was added:

9.6

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.

Consequently, in C++14 bit-fields of type plain int are signed and the code posted is guaranteed to work as intended.

like image 119
101010 Avatar answered Sep 28 '22 07:09

101010