12

I have a code which uses bit-fields declared as follows

typedef struct my{ const char *name; uint8_t is_alpha : 1; uint8_t is_hwaccel : 1; uint8_t x_chroma_shift; uint8_t y_chroma_shift; } mystr; 

uint8_t is typedef'ed to unsigned char.

Building the code in MS-VS 2008 using this bit fields gives a warning as below:

imgconvert.c(60) : warning C4214: nonstandard extension used : bit-field types other than int.
  1. Is there any problems/potential issues in using bit fields of type other than int? Why the warning?
  2. Are other than int type bit-fileds they allowed by C99 C language specification?
5
  • 1
    The warning is pretty self-explanatory: nonstandard extension used ; your code may have portability problems. Commented Feb 17, 2010 at 12:28
  • @Mehrad:Using type int is useful from portability aspects only if all targets/compiler have same sized ints. Commented Feb 17, 2010 at 12:51
  • you are writing about bitfields here, their size is specified in the code. Commented Feb 17, 2010 at 13:27
  • 1
    The problem is not the size of the bitfield (it is specified) but the size of the maximum bitfield (no larger than the type) or the padding (two 1 bits are packed in 8bit int with 6 unused bits, for a int it would be 2 used and 30 free). Commented Mar 7, 2016 at 22:39
  • Another thread you may be interested in: stackoverflow.com/questions/54719855/… Commented Feb 18, 2019 at 3:31

3 Answers 3

6

1] Is there any problems/potential issues in using bit fields of type other than int? Why the warning?

Since bit-fields are low-level, there may be issues with portability if you are using non-standard types. Hence the warning -- note it is still a warning and not an error.

2] Are other than int type bit-fileds they allowed by C99 C language specification?

From the draft of C99:

6.7.2.1 Structure and union specifiers

4 A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type.

Sign up to request clarification or add additional context in comments.

10 Comments

Isn't "some other implementation-defined type" remarkably useless in a standards document?
@Neil Butterworth: ATM, I just have the draft. Will need to look up the actual though. But, yes, I guess you are right.
@dirkgently: Using type int is useful from portability aspects only if all targets/compiler are guaranteed to have same sized ints. Is this a reasonable assumption. I dont know thats why i am asking.
@goldenmean: No, the standard gurantess only char to have the same size across all machines. The size of an intis defined only as a range so it's not very useful from the portability perspective. The stdint header was added for this purpose to C99. I guess you should be okay with the warning.
@dirkgently, sizeof(char) is one, but that doesn't mean CHAR_BIT is the same on all platforms.
|
2

Why not use int? The actual implementation of bitfields varies from compiler to compiler. If you want to write portable code, use int. If you want to create a small structure, or a structure of a fixed number of bytes, or a structure where the bits are in a fixed position, don't use bitfields. Create a uint8_t member called something like flags and define macros to use as bitmasks.

3 Comments

You mean unsigned int. uint8_t is unsigned, int is signed, mixing them is no good.
I haven't personally used bitfields in code, but if it's a 1-bit bitfield, does the sign matter?
@tomlogic Yes, sign matters. A 1-bit signed field has one sign bit and zero value bits. Hence 1-bit signed fields are expressly forbidden in MISRA C and other standards.
0

As others have mentioned about portability issues et al, if you didn't know you can just disable the warning via the warning pragma:
https://learn.microsoft.com/en-us/cpp/preprocessor/warning?view=vs-2019

#pragma warning(push) #pragma warning(disable: 4214) // warning C4214: nonstandard extension used: bit field types other than int typedef struct my{ const char *name; uint8_t is_alpha : 1; uint8_t is_hwaccel : 1; uint8_t x_chroma_shift; uint8_t y_chroma_shift; } mystr; #pragma warning(pop) 

Also you can disable specific warnings in your project properties but then they are project wide. This way you can control them per data type.

Then if you are ever not sure 100% what kind of binary code MSVC will generate for these either run it in the debugger and look at the "disassembly view" (break on where it gets accessed), or load up your executable (with PDB file for symbols) in a disassembler like IDA Pro, Ghidra, etc.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.