Visual Studio 2013 WDK8.1 - bitfields

I’m trying to compile my SCSI tape drivers for 32-bit and 64-bit using Visual Studio 2013 and WDK 8.1 (don’t laugh). I notice that there are no tape driver samples in the WDK - or have I missed something?

This doesn’t compile:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;

warning C4214: nonstandard extension used : bit field types other than int

I could put a #pragma warning(suppress:4214) in front of every UCHAR, but is there a better way? /Ze doesn’t work as it’s been deprecated.

Regards, Richard.

xxxxx@compuserve.com wrote:

I’m trying to compile my SCSI tape drivers for 32-bit and 64-bit using Visual Studio 2013 and WDK 8.1 (don’t laugh). I notice that there are no tape driver samples in the WDK - or have I missed something?

This doesn’t compile:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;

warning C4214: nonstandard extension used : bit field types other than int

I could put a #pragma warning(suppress:4214) in front of every UCHAR, but is there a better way?

Sure there is. Do what the warning suggests:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UINT PageCode : 6;
UINT Reserved1 : 2;
UCHAR PageLength;
UINT Reserved2 : 6;
UINT DCC : 1;
UINT DCE : 1;
UINT Reserved3 : 5;
UINT RED : 2;
UINT DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Use #pragma warning(disable:4214) … #pragma warning(default:4214) around
the whole structure.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@compuserve.com
Sent: Thursday, August 28, 2014 12:34 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Visual Studio 2013 WDK8.1 - bitfields

I’m trying to compile my SCSI tape drivers for 32-bit and 64-bit using
Visual Studio 2013 and WDK 8.1 (don’t laugh). I notice that there are no
tape driver samples in the WDK - or have I missed something?

This doesn’t compile:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;

warning C4214: nonstandard extension used : bit field types other than int

I could put a #pragma warning(suppress:4214) in front of every UCHAR, but
is there a better way? /Ze doesn’t work as it’s been deprecated.

Regards, Richard.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

While changing the UCHAR’s to UINTs eliminates the compiler warning.
This is a SCSI structure (from a MS WDK header). It needs to be packed
properly. Don’s suggestion is the way to go.

On 8/28/2014 9:39 AM, Tim Roberts wrote:

xxxxx@compuserve.com wrote:
> I’m trying to compile my SCSI tape drivers for 32-bit and 64-bit using Visual Studio 2013 and WDK 8.1 (don’t laugh). I notice that there are no tape driver samples in the WDK - or have I missed something?
>
> This doesn’t compile:
>
> typedef struct _MODE_DATA_COMPRESSION_PAGE {
> UCHAR PageCode : 6;
> UCHAR Reserved1 : 2;
> UCHAR PageLength;
> UCHAR Reserved2 : 6;
> UCHAR DCC : 1;
> UCHAR DCE : 1;
> UCHAR Reserved3 : 5;
> UCHAR RED : 2;
> UCHAR DDE : 1;
> UCHAR CompressionAlgorithm[4];
> UCHAR DecompressionAlgorithm[4];
> UCHAR Reserved4[4];
> } MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;
>
> warning C4214: nonstandard extension used : bit field types other than int
>
> I could put a #pragma warning(suppress:4214) in front of every UCHAR, but is there a better way?
Sure there is. Do what the warning suggests:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UINT PageCode : 6;
UINT Reserved1 : 2;
UCHAR PageLength;
UINT Reserved2 : 6;
UINT DCC : 1;
UINT DCE : 1;
UINT Reserved3 : 5;
UINT RED : 2;
UINT DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;

In 2008R2+, MS kind of phased the tape support out.

Jeff Glass wrote:

While changing the UCHAR’s to UINTs eliminates the compiler warning.
This is a SCSI structure (from a MS WDK header). It needs to be packed
properly. Don’s suggestion is the way to go.

The Microsoft headers that include this already have the pragma to
disable 4214.

However, changing from UCHAR to UINT for the bitfields will not change
the packing in any way. Some people have developed a rule in their
brains that the type of a bitfield should be the smallest type that fits
the field size. That’s a false rule. The C and C++ standards have both
always mandated that the type of a bitfield should be either “int” or
“unsigned int” (and Microsoft’s compiler happens to have an extension
that allows “__int64” and “unsigned __int64” for fields larger than 32
bits).

There is no advantage to using “unsigned char” or “unsigned short” over
“unsigned int” in a bitfield, and using “unsigned int” makes you
standard-compliant.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

With respect to the headers containing the pragma, that’s only true in
newer headers. The original poster may be using the header out of a WDK
or DDK that had tape samples (like 3790.1830) but doesn’t have a pragma
in minitape.h.

With respect to the bit field packing, I tested this before I replied
with a quick console app. It does change the packing (at least with VS
2008).

typedef struct _MODE_DATA_COMPRESSION_PAGE_P {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE_P, *PMODE_DATA_COMPRESSION_PAGE_P;

typedef struct _MODE_DATA_COMPRESSION_PAGE_I {
UINT PageCode : 6;
UINT Reserved1 : 2;

UCHAR PageLength;

UINT Reserved2 : 6;
UINT DCC : 1;
UINT DCE : 1;
UINT Reserved3 : 5;
UINT RED : 2;
UINT DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE_I, *PMODE_DATA_COMPRESSION_PAGE_I;

int _tmain(int argc, _TCHAR* argv)
{
MODE_DATA_COMPRESSION_PAGE_P p = {0};
MODE_DATA_COMPRESSION_PAGE_I i = {0};

p.Reserved2 = 1;
i.Reserved2 = 1;

printf( “Header struct\n”);
DumpBuffer(&p, sizeof(p));
printf( “\nTim’s struct\n” );
DumpBuffer(&i, sizeof(i));

return 0;
}

Header struct
00000000 00 00 01 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Tim’s struct
00000000 00 00 00 00 00 01 00 00 - 00 00 00 00 00 00 00 00
00000010 00 00 00 00 00

On 8/28/2014 10:41 AM, Tim Roberts wrote:

Jeff Glass wrote:
> While changing the UCHAR’s to UINTs eliminates the compiler warning.
> This is a SCSI structure (from a MS WDK header). It needs to be packed
> properly. Don’s suggestion is the way to go.
The Microsoft headers that include this already have the pragma to
disable 4214.

However, changing from UCHAR to UINT for the bitfields will not change
the packing in any way. Some people have developed a rule in their
brains that the type of a bitfield should be the smallest type that fits
the field size. That’s a false rule. The C and C++ standards have both
always mandated that the type of a bitfield should be either “int” or
“unsigned int” (and Microsoft’s compiler happens to have an extension
that allows “__int64” and “unsigned __int64” for fields larger than 32
bits).

There is no advantage to using “unsigned char” or “unsigned short” over
“unsigned int” in a bitfield, and using “unsigned int” makes you
standard-compliant.

Additionally, if the UCHAR bitfield didn’t pack differently than the
UINT bitfield, the structure in the MS header wouldn’t be SCSI compliant.

On 8/28/2014 10:41 AM, Tim Roberts wrote:

Jeff Glass wrote:
> While changing the UCHAR’s to UINTs eliminates the compiler warning.
> This is a SCSI structure (from a MS WDK header). It needs to be packed
> properly. Don’s suggestion is the way to go.
The Microsoft headers that include this already have the pragma to
disable 4214.

However, changing from UCHAR to UINT for the bitfields will not change
the packing in any way. Some people have developed a rule in their
brains that the type of a bitfield should be the smallest type that fits
the field size. That’s a false rule. The C and C++ standards have both
always mandated that the type of a bitfield should be either “int” or
“unsigned int” (and Microsoft’s compiler happens to have an extension
that allows “__int64” and “unsigned __int64” for fields larger than 32
bits).

There is no advantage to using “unsigned char” or “unsigned short” over
“unsigned int” in a bitfield, and using “unsigned int” makes you
standard-compliant.

You should not write:

typedef struct _MODE_DATA_COMPRESSION_PAGE_I{
UINT PageCode : 6;
UINT Reserved1 : 2;

UCHAR PageLength;

}

Because the compiler does this:

typedef struct _MODE_DATA_COMPRESSION_PAGE_I {
UINT PageCode : 6;
UINT Reserved1 : 2;
// This field is added by the compiler
UINT Spare1:24; // a UINT bitfield is 32 bits large.
UCHAR PageLength; // This field has offset 4 (in bytes) and not 1.

}

You should always add this additional field yourself.

But you have exactely four UCHARs in a row (the size of an INT), so does this definition work:

// Save the current packing size
#pragma pack(push)
// Ensures no padding is added after an INT.
#pragma pack(4)
typedef struct _MODE_DATA_COMPRESSION_PAGE_I {
INT PageCode : 6;
INT Reserved1 : 2;
INT PageLength:8;
INT Reserved2 : 6;
INT DCC : 1;
INT DCE : 1;
INT Reserved3 : 5;
INT RED : 2;
INT DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE_I,*PMODE_DATA_COMPRESSION_PAGE_I;

// Restore the previous packing size
#pragma pack(pop)
//
// Fail on compilation if the following
// fields do not have the desired offset
//
C_ASSERT(FIELD_OFFSET(MODE_DATA_COMPRESSION_PAGE_I,CompressionAlgorithm) == 4);
C_ASSERT(FIELD_OFFSET(MODE_DATA_COMPRESSION_PAGE_I,DecompressionAlgorithm) == 8);
C_ASSERT(FIELD_OFFSET(MODE_DATA_COMPRESSION_PAGE_I,Reserved4) == 12);

Thanks everyone for the useful lesson in #pragma, C structs and bit fields and portability issues.

Jan
I agree with you about not relying on structs to have a specific memory layout.
If I was in the mood for a complete rewrite, I would remove the structs and do explicit bit packing/unpacking (and if on the VAX I would use LIB$EXTZV and LIB$INSV to do this).

I’ve just discovered minitape.h in C:\Program Files x86)\Windows Kits\8.1\minitape.h
which has:

#if defined(_MSC_VER) && (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(push)
#endif
#pragma warning(disable:4200) /* nonstandard extension used : zero-sized array in struct/union */
#pragma warning(disable:4201) /* nonstandard extension used : Nameless struct/union */
#pragma warning(disable:4214) /* nonstandard extension used : Bit field types other than int */
#endif

and

#if defined(_MSC_VER) && (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(pop)
#else
#pragma warning(default:4200) /* nonstandard extension used : zero-sized array in struct/union */
#pragma warning(default:4201) /* nonstandard extension used : Nameless struct/union */
#pragma warning(default:4214) /* nonstandard extension used : Bit field types other than int */
#endif
#endif

surrounding the entire file.

It also has some worrying new stuff like NTDDI_VERSION and #pragma pack() which were not present in previous versions.
Thanks again, Richard.

NTDDI_VERSION showed up in the vista ddk, nothing new.

d

Bent from my phone


From: xxxxx@compuserve.commailto:xxxxx
Sent: ?8/?28/?2014 11:31 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE: Re: Re: [ntdev] Visual Studio 2013 WDK8.1 - bitfields

Thanks everyone for the useful lesson in #pragma, C structs and bit fields and portability issues.

Jan
I agree with you about not relying on structs to have a specific memory layout.
If I was in the mood for a complete rewrite, I would remove the structs and do explicit bit packing/unpacking (and if on the VAX I would use LIB$EXTZV and LIB$INSV to do this).

I’ve just discovered minitape.h in C:\Program Files x86)\Windows Kits\8.1\minitape.h
which has:

#if defined(_MSC_VER) && (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(push)
#endif
#pragma warning(disable:4200) /* nonstandard extension used : zero-sized array in struct/union /
#pragma warning(disable:4201) /
nonstandard extension used : Nameless struct/union /
#pragma warning(disable:4214) /
nonstandard extension used : Bit field types other than int /
#endif

and

#if defined(_MSC_VER) && (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(pop)
#else
#pragma warning(default:4200) /
nonstandard extension used : zero-sized array in struct/union /
#pragma warning(default:4201) /
nonstandard extension used : Nameless struct/union /
#pragma warning(default:4214) /
nonstandard extension used : Bit field types other than int */
#endif
#endif

surrounding the entire file.

It also has some worrying new stuff like NTDDI_VERSION and #pragma pack() which were not present in previous versions.
Thanks again, Richard.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

On 28-Aug-2014 21:20, Jeff Glass wrote:

With respect to the bit field packing, I tested this before I replied
with a quick console app. It does change the packing (at least with VS
2008).

typedef struct _MODE_DATA_COMPRESSION_PAGE_P {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE_P, *PMODE_DATA_COMPRESSION_PAGE_P;

When converting to standard UINT bitfields, PageLength should be also
made a bit field:

typedef struct _MODE_DATA_COMPRESSION_PAGE_I {
UINT PageCode : 6;
UINT Reserved1 : 2;
UINT PageLength: 8; <<< this
UINT Reserved2 : 6;

By the way, GCC has a compatibility option to emulate
Microsoft C bit fields behavior; the explanation
in the GCC manual can be useful.
(search for “ms_struct” and “gcc_struct”)

Regards,
– pa

To resume all of this:

  • that’ why I hate bit fields :slight_smile: especially for single-bit boolean flags.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

“Jan Bottorff” wrote in message news:xxxxx@ntdev…
Since we are talking about better practices…

I’ll bring up the strategy something like (excuse the email line wrapping):

#define PLATFORM_WINDOWS_BEGIN_ALLOW_BYTE_BITFIELDS __pragma(warning(push));__pragma(warning(disable:4214));

#define PLATFORM_WINDOWS_END_ALLOW_BYTE_BITFIELDS __pragma(warning(pop));

#ifdef PLATFORM_WINDOWS

// set platform specific compiler directives to make strut shape correct
#define PLATFORM_NEUTRAL_BEGIN_PACKED_STRUCT \ PLATFORM_WINDOWS_BEGIN_ALLOW_BYTE_BITFIELDS

#define PLATFORM_NEUTRAL_END_PACKED_STRUC \ PLATFORM_WINDOWS_END_ALLOW_BYTE_BITFIELDS

#endif

We could debate about the pros and cons of push/pop vs enable/disable.

So then your wrap this define around your structure. My experience of making structures platform portable is you need to have some #defined symbols in assorted places, and some platforms may define some of these as empty, and other platforms define them with what’s needed.

If I have to make code initially written in Linux work on Windows, I can get grumpy when I see lots of platform specific constructs spread in a million places. Instead of complaining about non-portable constructs it seems like a better plan to write code that is more portable. The__pragma statement is way better than #pramga as you can use it in a macro definition, and then have a platform appropriate set of #defines

My opinion REALLY is you should NEVER depend on a struct to have a specific memory layout, and you should have functions/objects/macros that pack and unpack a byte pointer to/from your unpacked structure. Explicit code to define the packing and unpacking means you’re documenting what the expected binary layout is. I don’t believe the C spec says anything about how compiler implementations will pack structures. I know it’s common for C code to do this, but based on the C spec, the layout is undefined. C code can be quite portable, if you stop directly using all the little “enhancements” vendors like to make available. Struct packing also does not deal with endian issues. I suppose an argument for struct packing is the debugger will show you the bit fields, although the debugger will not do endian conversion, so you may or may not be able to see the fields in a debugger.

One quite portable C code bitfield strategy I’ve seen was GetBitField/SetBitField macros, that take a buffer pointer, bit offset bit width, and value as parameters. They use a bunch of shifting and masking which looks inefficient but after being optimized by the compiler is pretty much the same code you get from the platform dependent struct shape. These macros also dealt with endian issues, and came in a couple flavors based on what endian the buffers uses.

I also understand there are some really special cases, especially for kernel code, where you will need to control the layout, like certain instructions require the data to be aligned in a certain way. Like if you want some value to be in it’s own cache line.

A better strategy might also be to have things like protocol messages defined in some description language, and you preprocess that language into .c/h files for your specific platform. This has the huge advantage you can also process the message descriptions into the language used by the your network sniffer, so if you change a message during development, the code and the tools all automatically stay in sync. And you can process the message descriptions into documentation. No matter how carefully you make you struct C packing, it still is a C structure, not a language independent description of a memory layout.

Jan

#pragma warning(pop)

Sent from Surface Pro

From: Don Burn
Sent: ‎Thursday‎, ‎August‎ ‎28‎, ‎2014 ‎12‎:‎40‎ ‎PM
To: Windows System Software Devs Interest List

Use #pragma warning(disable:4214) … #pragma warning(default:4214) around
the whole structure.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@compuserve.com
Sent: Thursday, August 28, 2014 12:34 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Visual Studio 2013 WDK8.1 - bitfields

I’m trying to compile my SCSI tape drivers for 32-bit and 64-bit using
Visual Studio 2013 and WDK 8.1 (don’t laugh). I notice that there are no
tape driver samples in the WDK - or have I missed something?

This doesn’t compile:

typedef struct _MODE_DATA_COMPRESSION_PAGE {
UCHAR PageCode : 6;
UCHAR Reserved1 : 2;
UCHAR PageLength;
UCHAR Reserved2 : 6;
UCHAR DCC : 1;
UCHAR DCE : 1;
UCHAR Reserved3 : 5;
UCHAR RED : 2;
UCHAR DDE : 1;
UCHAR CompressionAlgorithm[4];
UCHAR DecompressionAlgorithm[4];
UCHAR Reserved4[4];
} MODE_DATA_COMPRESSION_PAGE, *PMODE_DATA_COMPRESSION_PAGE;

warning C4214: nonstandard extension used : bit field types other than int

I could put a #pragma warning(suppress:4214) in front of every UCHAR, but
is there a better way? /Ze doesn’t work as it’s been deprecated.

Regards, Richard.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@live.fr wrote:

You should not write:

typedef struct _MODE_DATA_COMPRESSION_PAGE_I{
UINT PageCode : 6;
UINT Reserved1 : 2;

UCHAR PageLength;

}

OK, to a great extent, we’re arguing about how many angels can dance on
the head of a pin here, and I’m playing devil’s advocate. (Is that a
mixed metaphor?)

Using UCHAR in the structure definition makes the source code prettier
to look at. That is not a trivial consideration, and given the
circumstances, I might keep it for just that reason.

However, your advice “you should not write” is not legitimate. After
all, both language standards say that’s exactly what you SHOULD write.
Assuming you WANT to write ISO-compliant code, there are two correct
answers. One answer is not to mix bitfield and non-bitfield fields in
the same structure:
UINT PageCode : 6;
UINT Reserved1 : 2;
UINT PageLength : 8;

The other correct answer is to explicitly alter the packing rules using
#pragma pack(push, 1)
or
#include <pshpack1.h>

I was wrong in my assertion that it didn’t already the padding. I
should have known better. Because I work with so many canned formats, I
have a tendency to set the packing to 1 any time I’m defining structures
like that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</pshpack1.h>

If you write UINT64 bitfields than you must have a total of 64 bits, 32 bits for UINT bitfields, 16 bits for USHORT bitfields and 8 bits for a UCHAR bitfields.

That’s all what my post was about.

>Worse than that, the C standards don’t even mandate whether bitfields are laid out left-to-right or

right-to-left. So:

Correct.

This depends on whether the platform is big- or little-endian, and C is supported on both.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

On Aug 31, 2014, at 1:56 PM, Maxim S. Shatskih wrote:

>> Worse than that, the C standards don’t even mandate whether bitfields are laid out left-to-right or
>> right-to-left. So:
>
> Correct.
>
> This depends on whether the platform is big- or little-endian, and C is supported on both.

No, actually, it doesn?t. The compiler is free to choose the bitfield order ? endianness isn?t involved There may be sensible choices, but the standard doesn?t mandate them.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Out of curiosity, I did a Google search on "C bitfield extract macro? wondering if there is a common (BSD type license) set of bitfield macros.

To my amazement, it looks like using compiler independent C macros for bitfield manipulation is patented, see http://www.google.com/patents/US6938241

Right about now I?d love to say lots of things about the patent system that would be inappropriate to post on ntdev.

Jan

On Sep 1, 2014, at 10:35 PM, Tim Roberts wrote:

> On Aug 31, 2014, at 1:56 PM, Maxim S. Shatskih wrote:
>
>>> Worse than that, the C standards don’t even mandate whether bitfields are laid out left-to-right or
>>> right-to-left. So:
>>
>> Correct.
>>
>> This depends on whether the platform is big- or little-endian, and C is supported on both.
>
> No, actually, it doesn?t. The compiler is free to choose the bitfield order ? endianness isn?t involved There may be sensible choices, but the standard doesn?t mandate them.
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hmm. I don’t know whether the process Joel Spolsky used in the following blog post applies to granted patents, but if it does, the patent in question certainly deserves the same fate.

http://www.joelonsoftware.com/items/2013/07/22.html

Phil

Not speaking for LogRhythm
Phil Barila | Senior Software Engineer
720.881.5364 (w)
LogRhythm, Inc.
The Security Intelligence Company
A LEADER in Gartner’s SIEM Magic Quadrant (2012-2014)
Perfect 5-Star Rating in SC Magazine (2009-2014)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Jan Bottorff
Sent: Tuesday, September 02, 2014 2:07 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Visual Studio 2013 WDK8.1 - bitfields

Out of curiosity, I did a Google search on “C bitfield extract macro” wondering if there is a common (BSD type license) set of bitfield macros.

To my amazement, it looks like using compiler independent C macros for bitfield manipulation is patented, see http://www.google.com/patents/US6938241

Right about now I’d love to say lots of things about the patent system that would be inappropriate to post on ntdev.

Jan

On Sep 1, 2014, at 10:35 PM, Tim Roberts wrote:

> On Aug 31, 2014, at 1:56 PM, Maxim S. Shatskih wrote:
>
>>> Worse than that, the C standards don’t even mandate whether
>>> bitfields are laid out left-to-right or right-to-left. So:
>>
>> Correct.
>>
>> This depends on whether the platform is big- or little-endian, and C is supported on both.
>
> No, actually, it doesn’t. The compiler is free to choose the bitfield order - endianness isn’t involved There may be sensible choices, but the standard doesn’t mandate them.
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Wow… Considering the things that we’ve determined ARE appropriate to post on NTDEV, what you’d like to say must *really* be something :wink:

Peter
OSR
@OSRDrivers