Reason behind MISRA rule 111

Hi,

I am just curious to know what the reason behind MISRA rule 111.

The rule says - Bit fields shall only be defined to be one of type unsigned int or signed int

I have used UINT32 instead of unsigned int in my code but compiler has thrown a warning says - "field type should be int"

Could somebody please put light on this.

Thanks Vikas

--------------------------------------- Posted through

formatting link

Reply to
vikasvds
Loading thread data ...

According to C99:

"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"

Assuming UINT32 is implemented as 'unsigned long', it falls in the 'implementation-defined' category, which is not portable.

Reply to
Arlet Ottens

"Unsigned int" and "signed int" are the only types that are guaranteed to be available by any C compiler. Other types typically work with most compilers, but may have different sizes or alignments on different targets or compilers. For example, if you use an enumerated type, one compiler may align it to 8-bit boundaries, whereas another might align it to "int" boundaries (16-bit or 32-bit).

If you are careful to make sure your code is as portable as it needs to be, and that sizes and alignments are correct on your target, then I personally see no reason to follow this rule. Using specific types correctly is an important aspect of writing clear and correct code.

Reply to
David Brown

On top of the reasons other people have posted, think about this for a bit. A bitfield already has a defined field length, given when you specify it. By declaring a UINT32, you're calling out a typedef that also has a defined field length.

If the bitfield you're calling out is 32 bits long you're simply being redundant. If it's anything other than that, you're conflicting with yourself. In neither case has declaring the bitfield to be of type UINT32 provided you with any advantage.

--
Rob Gaddi, Highland Technology
Email address is currently out of order
Reply to
Rob Gaddi

Which is irrelevant.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

In message , vikasvds writes

Not here they can't.

Try

formatting link

and go to the forum where you will get the definitive answer.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

That's not the whole story. When you pick a type for a bitfield, you give several things - one is the /maximum/ allowed bitlength (such as 32 bits in this case).

Another is the alignment. For example, if you write "struct { uint8_t a : 2; uint32_t b : 4; } bits" then bits.a will be at the start of the structure, followed by padding to allow b to fit within the next 32-bit alignment block.

You also affect the type of the extracted field - with the above structure on a 16-bit machine, "a" will be promoted to 16-bit int if you use it in arithmetic, while "b" will be promoted to 32-bit uint after extraction.

And if you have declared the bitfield to be volatile (or its components as volatile), then the underlying type may have some effect on the instructions used to access the data. However, I don't think this is well defined by C, and compilers are not consistent.

Bitfields have their uses, but you definitely want to check your compiler and what it is generating - don't expect them to be portable.

Reply to
David Brown

No, it's not. Portable C code has _no_ control over alignment whatsoever, particularly not regarding bitfields.

No. Nothing in the language definition requires any padding in this case. That struct can perfectly legally fit into a single byte.

Not necessarily, given that any compiler, including the one for that unspecifited "16-bit machine" may not even allow you to _compile_ that code, much less do what you think it should with it.

Actually from the point of view of MISRA C you have that backwards. The moment you use any information you needed to check your compiler manual for, you've left common ground, and made your code unportable.

Reply to
Hans-Bernhard Bröker

e
l

Using bitfields and expecting a certain representation is unportable any= way, as the Endianess of bit-fields is implementation-defined.

Vinzent.

--

A C program is like a fast dance on a newly waxed dance floor by people =
carrying
razors.
   --  Waldi Ravens
Reply to
Vinzent Hoefler

A lot of stuff is implementation defined, such as representation of integers and floats. It doesn't have to be a problem, unless you move the binary representation from one implementation to another.

If you use the bitfields only internally, there are no portability concerns.

Reply to
Arlet Ottens

You are wrong

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

You are correct - /portable/ C does not define alignment for bitfields.

But /practical/ C does - different compilers use different methods, and it can make a difference to the layout, alignment and padding of the fields. It may also affect the instructions used and the width of the accesses.

As you say, /portable/ C has no control over alignment of bitfields - the C standards don't give any guidelines. It is up to the compiler, along with the standard ABI for the target, to determine the implementation. And for some implementations, the choice of the underlying type of the bitfield will influence the layout.

Correct - and yet some /implementations/ will pad it into two bytes, or even more. A compiler could justify using 8 bytes for this struct (though the ones I tested with used 1 or 2 bytes).

Here, I think, you are wrong. The C standards only allow int, signed int and unsigned int as bitfield types - C99 also allows _Bool. In each case, the extracted field is given the type used in the bitfield declaration. C++ allows any integral type, including enumerations, as bitfield types - and again, on extraction the data takes on this type. Many C compilers allow other integral types in bitfields, and they follow the same rules as with C++.

Again, this is not something in the C standards - it is something from practical reality. /If/ a compiler supports more general bitfield types, /then/ it will treat them as that type when the bitfield is extracted.

Bitfields are /always/ unportable. If nothing else, there is no standard defining the ordering of bitfields. Some compilers order them from the LSB, others from the MSB. MS Visual C++ actually changed this order between two versions of the compiler!

So if you are writing portable code, you can't rely on bitfield details. It's fine if all you want to do is pack some data into a smaller space, for use entirely within a program. It is also okay to use them for inherently unportable code, such as for hardware registers - but you must check that your bitfield structure actually matches the hardware.

Given these limitations, I'm actually surprised MISRA allows them at all.

Reply to
David Brown

In message , David Brown writes

MISRA has no view on portability as such.

--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills  Staffs  England     /\/\/\/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
Reply to
Chris H

Indeed. And that's why every statement such as yours above claiming bitfields behave in any particular way is wrong by default. At the very minimum such a statement would have to be qualified by the exact version of a particular compiler it's supposed to be applicable for. Often the exact flags have to be specified, too.

But you didn't say it "can". You say it _does_, without any restriction. That's where your claim became incorrect by insufficiently justified generalization.

Yet you effectively claimed that they _all_ did so. And that again is an unjustified generalization.

Relying on the behaviour of such non-standard bitfield types on usage is every bit as unportable as their very existence.

Extensions to the language can behave whichever way they want. Yes, they'll usually behave sanely, following the guidance set forth by standard elements of the language. But there's no guarantee either way.

"Many" is an unreliable subset.

And what evidence other than "I have never seen otherwise" do you have for that claim?

No. Only relying on implementation-specific information about them makes them so. That's why I advised against even looking at that information. You can't abuse information you don't have.

Reply to
Hans-Bernhard Bröker

Point taken. What I really meant was that it these are factors that /could/ be affected by the choice of underlying type - as we know, there are no guarantees here.

Agreed.

True.

There are a number of features in C that are implementation dependent, rather than being fixed by the standards. If your code relies on any of these features, you have to check how it works on the particular target and compiler combination you are using. Bitfields are just an area in which there are particularly many implementation-dependent issues.

And of course just because the standards happen to be clear on a particular point, does not mean that any given compiler will actually follow them!

I haven't much more evidence, I admit - other than to claim that compiler writers who implement such extensions would normally do so in the clearest and most sensible way.

If you know of counter examples, I'll be happy to accept them. And I will try to be more careful to qualify my points in this thread - though I think it is fairly clear that the lack of standards and consistency around bitfields makes /all/ points somewhat vague.

Reply to
David Brown

By the same argument, 'int' and 'double' would be unportable as well. But they have very well-defined properties you can use. And as long as you use only those properties, your code is portable.

For example, a 'unsigned int foo : 1;' gives a neat place to store a bit. 100% portable. I use that all the time. It gets unportable when you 'memcpy' or 'fwrite' the structure containing it around, and make assumptions about the result. But that's no different for 'int' and 'double'.

Stefan

Reply to
Stefan Reuther

There is lots in C that is "implementation defined". Some aspects of "int" and "double" fall into this, such as their bit width. If you are writing portable code, you /do/ often avoid using "int" if the bit width is important. Instead, you use "int16_t", "uint32_t", or whatever you actually mean.

Bitfields have lots of implementation-defined behaviour, and are therefore often non-portable. But as you say, they have certain well-defined aspects - if you only need to rely on those aspects, then your code is portable.

Reply to
David Brown

The

ual

It is a problem, if you rely on a certain representation, "(unsigned) in= t" or not. So I don't think, this particular MISRA rule had close-to-100% portability in mind.

LOL.

It would be nice to use bitfields to define device register and that simply ain't possible in a "portable" (e.g. compiler-independent) way, because the representation may change once a different compiler has been=

chosen by the customer. BTSTFU.

The only "portable" way to use bitfields at that time was to define a collection of flags which were situated at something the Z80 programmer knows as zero-page to cut down code size by a couple of bytes because then direct bit addressing was possible. If that's all that bitfields can deliver, they sure are close to useless, I'd say.

Vinzent.

--

A C program is like a fast dance on a newly waxed dance floor by people =
carrying
razors.
   --  Waldi Ravens
Reply to
Vinzent Hoefler

I meant internally, only as a method to cram more data in the same memory. Using bitfields in device interfaces, is no longer 'internal'.

Still, you could define device registers using bitfields, if you include some #ifdef COMPILER_XYZ around it, followed by

#else #error Please add register definitions for this compiler #endif

Which exposes portability problems. Switching compilers mid-project is pretty rare anyway, and very few embedded projects are 100% portable between compilers. Try implementing a portable interrupt handler, for instance.

Reply to
Arlet Ottens

Why do you *care* what MISRA has to say? Considering "rules" to be anything other than "guidelines" abrogates your design responsibilities to some dweeb who *thinks* he can foresee everything that you *might* do "wrong" and opt to protect you from yourself. *At* some expense (reliability, cost, maintainability, etc.)

Most *guidelines* point out issues that a conscientious designer should already be aware of -- undefined behaviors in The Standard, compiler-specific variations, etc. Avoiding something *simply* because a piece of paper says "you might get screwed" is intended for The Mindless Masses who don't/can't think things through. ("Don't run with scissors" -- "But, if I *walk*, the patient will be *dead* before I get there!")

It's simplistic to think that imposing a simple set of "rules" (so simple, in fact, that the compiler can check and enforce them!) is going to make a dramatic difference. "Yes, I dotted all my i's and crossed all my t's... but I still don't know the difference between a noun and a verb..."

Figure out what your client/user/industry requires and *try* to adhere to that. But, most of all, *understand* why your client wants to impose those constraints and make sure that your *client* understands the consequences of those constraints. E.g., writing code for a *gaming* system to MISRA is one sure way to get yourself laughed out of the regulatory process! (I suspect DoD would simply smile at you and tell you to go back and "do it over"...)

*If* your client insists on MISRA compliance, write your code to suppress all of those warnings, shrug your shoulders and cash their check letting them *think* they "bought something (MISRA compliance) worthwhile". [this is often the path of least resistance rather than trying to educate them to the folly behind this -- "write in ADA and software quality will improve"...]

Good luck!

Reply to
D Yuniskis

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.