EmbeddedRelated.com
Forums

Reason behind MISRA rule 111

Started by vikasvds May 12, 2011
D Yuniskis wrote:
> On 5/16/2011 10:05 AM, Stefan Reuther wrote: >> &#4294967295;7.1 "Octal constants [...] shall not be used." How does my code get any >> better if I have to specify file permissions in hex (or with lengthy >> constants)? Everyone knows what mode 0755 is. But do you know what >> S_IRWXO is (without looking up the octal value)? > > Actually, I really *hate* the way octal is indicated in C. > I much prefer the <value>r<radix> notation. It is extensible > (to other radix), unambiguous, doesn't add much clutter to > the code and doesn't "magically" assign extra value to things > like leading zeroes.
Agreed. But still we have that syntax and have to live with it.
> (I got bit by #include-ing some tables of constants that were > created with leading zero padding instead of leading spaces)
And that's precisely the point why I believe ruling it out makes no sense: people have to know it anyway. You don't save any teaching effort. If you say "don't use <pthread.h>", you can save yourself all multi-threading teaching effort. But not if you say "don't use octal", because people will hit it by accident.
>> &#4294967295;20.5 "The error indicator errno shall not be used." How does my code >> get any better when I ignore errors from 'fopen'? > > Isn't there *also* a requirement that "error values" from functions > be explicitly tested (e.g., malloc returning NULL)? So, test it > everywhere *except* those cases where a mechanism has explicitly been > created for this purpose.
Of course I test return values where it matters. The problem is again people who want to enforce some rules, and oversee that it doesn't always matter. For an example, look at the trouble generated by the gcc function attribute "warn_unused_result" which is applied to the functions read() and write() in recent libcs. A popular method of inter-process signalisation is a pipe, where one end writes a character to wake the other end. So I have this pipe fd, open with O_NONBLOCK, and I write a character into it: write(fd, "", 1); I don't care whether it fails. Because that means the pipe is full and the other end will wake up soon, which is what I want. This gives a warning. WHICH CANNOT BE TURNED OFF. I have to uglify my code, like this, int result = write(fd, "", 1); if (result == 0) { } to get rid of the warning. Just assigning it to a variable is not enough, because then I have a variable which was assigned but not used. Wonderful.
> (how do you code for range errors on something like pow(a,b) if > you can't look at errno? do you try to detect the error in the > *domain*, instead? *try* it! :> )
One of my favorite credos is "don't check for an error you don't know how to handle", which goes nicely along with the popular pow() implementations that don't set errno :-) Stefan
Stefan Reuther wrote:

> write(fd, "", 1); > I don't care whether it fails. Because that means the pipe is full and > the other end will wake up soon, which is what I want. This gives a > warning. WHICH CANNOT BE TURNED OFF. I have to uglify my code, like this, > int result = write(fd, "", 1); > if (result == 0) { }
(void) write (fd, "", 1); wouldn't work? Vinzent. -- A C program is like a fast dance on a newly waxed dance floor by people carrying razors. -- Waldi Ravens
Hi Stefan,

On 5/17/2011 10:11 AM, Stefan Reuther wrote:
>>> &#4294967295;7.1 "Octal constants [...] shall not be used." How does my code get any >>> better if I have to specify file permissions in hex (or with lengthy >>> constants)? Everyone knows what mode 0755 is. But do you know what >>> S_IRWXO is (without looking up the octal value)? >> >> Actually, I really *hate* the way octal is indicated in C. >> I much prefer the<value>r<radix> notation. It is extensible >> (to other radix), unambiguous, doesn't add much clutter to >> the code and doesn't "magically" assign extra value to things >> like leading zeroes. > > Agreed. But still we have that syntax and have to live with it.
Yes. So, you make a *guideline* that effectively warns you of how you can screw yourself by using/not using a particular language feature, etc. "Invest in your staff", as I've said before. *Educate* them so they know how to write better code and *care* about writing better code (instead of "doing what it takes" to silence the policeman)
>> (I got bit by #include-ing some tables of constants that were >> created with leading zero padding instead of leading spaces) > > And that's precisely the point why I believe ruling it out makes no > sense: people have to know it anyway. You don't save any teaching > effort. If you say "don't use<pthread.h>", you can save yourself all > multi-threading teaching effort. But not if you say "don't use octal", > because people will hit it by accident.
Exactly. In my case, the problem was easy to spot: "Hmmm... why did this variable just get loaded with 66? The value should be much higher than that... yes, the acceleration profile (graph) shows something like 100, here. So, where did the 66 come from? Ah, '00102' isn't '102r10' but, rather, '102r8'! Need to 86 these leading zeroes..."
>>> &#4294967295;20.5 "The error indicator errno shall not be used." How does my code >>> get any better when I ignore errors from 'fopen'? >> >> Isn't there *also* a requirement that "error values" from functions >> be explicitly tested (e.g., malloc returning NULL)? So, test it >> everywhere *except* those cases where a mechanism has explicitly been >> created for this purpose. > > Of course I test return values where it matters. The problem is again > people who want to enforce some rules, and oversee that it doesn't > always matter. For an example, look at the trouble generated by the gcc > function attribute "warn_unused_result" which is applied to the > functions read() and write() in recent libcs. > > A popular method of inter-process signalisation is a pipe, where one end > writes a character to wake the other end. So I have this pipe fd, open > with O_NONBLOCK, and I write a character into it: > write(fd, "", 1); > I don't care whether it fails. Because that means the pipe is full and > the other end will wake up soon, which is what I want. This gives a > warning. WHICH CANNOT BE TURNED OFF. I have to uglify my code, like this, > int result = write(fd, "", 1); > if (result == 0) { } > to get rid of the warning. Just assigning it to a variable is not > enough, because then I have a variable which was assigned but not used. > Wonderful.
Exactly. Attempts to "legislate" rules force you to spend extra effort working around those rules. In the process, you either distort your code so that it is harder to read (requiring comments explaining why you did something that looks 'stupid': "To appease lint et al.") or add bugs (which is what the rules are supposedly trying to *prevent*). In either case, you break your "flow" of thought (productivity) by having to deal with some triviality. Like MS's Mr Paperclip "reminding" you of stuff while you are trying to concentrate on getting something *done*. I have a distinctive coding style in that I do lots of things you are told *not* to do. Whenever I do something that will raise eyebrows, I alert the reader/reviewer to that fact in my commentary and describe *why* I made that choice. This doesn't prevent someone who comes after me from tearing out all that code and replacing it with something more appropriate to his/her sensibilities. *But*, it shows that I have thought out the issue and cautions them to take similar care when/if they opt to replace/rewrite it. For example, I might *deliberately* order the expressions in a compound conditional to exploit something I know about the data that will be encountered (i.e., if expr1 is expensive to evaluate and expr2 is often FALSE, I might deliberately say "expr2 && expr1" instead of "if expr2 { if expr1 { } }" which would make the deliberate choice more obvious). But, my commentary would deliberately draw attention to this. "/* Here, There be Dragons */"
>> (how do you code for range errors on something like pow(a,b) if >> you can't look at errno? do you try to detect the error in the >> *domain*, instead? *try* it! :> ) > > One of my favorite credos is "don't check for an error you don't know > how to handle",
This seems to be the approach in much desktop software. Esp. things coded in C++ (where it seems obvious that some layer is probably throwing exceptions but the layers above aren't smart enough to deal with them and just terminate the application, instead.
> which goes nicely along with the popular pow() > implementations that don't set errno :-)
Yet, MISRA doesn't *want* you to look at errno. Instead, you should try to *guess* as to whether the function is trying to (or should) signal an error! And some PHB is going to be able to "sign off" on whether some particular set of "violations" are "acceptable"?? <frown> Hire competent people and invest in their skillsets. If you're afraid they'll take that "investment" elsewhere (i.e., quit), then make your workplace attractive enough that they don't *want* to quit (or, hope that other firms have adopted a similar policy and you can "inherit" some of *their* "enhanced" staff losses).
On 5/17/2011 11:40 AM, D Yuniskis wrote:
> Hi Stefan, > > On 5/17/2011 10:11 AM, Stefan Reuther wrote: >>>> &#4294967295;7.1 "Octal constants [...] shall not be used." How does my code get >>>> any >>>> better if I have to specify file permissions in hex (or with lengthy >>>> constants)? Everyone knows what mode 0755 is. But do you know what >>>> S_IRWXO is (without looking up the octal value)? >>> >>> Actually, I really *hate* the way octal is indicated in C. >>> I much prefer the<value>r<radix> notation. It is extensible >>> (to other radix), unambiguous, doesn't add much clutter to >>> the code and doesn't "magically" assign extra value to things >>> like leading zeroes. >> >> Agreed. But still we have that syntax and have to live with it. > > Yes. So, you make a *guideline* that effectively warns you > of how you can screw yourself by using/not using a particular > language feature, etc. "Invest in your staff", as I've said > before. *Educate* them so they know how to write better code > and *care* about writing better code (instead of "doing what it > takes" to silence the policeman) >
See, I'd say that the octal constants rule is the best example of where something that the tools will enforce coding style, rather than guidelines to be manually enforced, is beneficial. Octal constants serve almost no purpose now that we've standardized on 8 bit bytes. File permissions are an extremely rare exception, and can be handled easily through something along the lines of #define PERMISSION(owner, group, world) (((owner) << 6) | ((group) << 3) | (world)) Most often, if you've got a leading zero it's a mistake, not a decision to invoke an octal. This is the sort of thing that humans are great at missing, leading to costly debugging time, whereas compilers are great at catching. Other examples include if (x == 0) do_this(); do_that(); When you've got coding styles that are so easy to make mistakes with, and offer little value, then letting the tools enforce them as restrictions, rather than guidelines, absolutely improves reliability. I certainly don't agree with everything in the MISRA spec. But to say that setting down hard fast rules has no value just doesn't add up. -- Rob Gaddi, Highland Technology Email address is currently out of order
Hi Rob,

On 5/17/2011 12:12 PM, Rob Gaddi wrote:
>> On 5/17/2011 10:11 AM, Stefan Reuther wrote: >>>>> &#4294967295;7.1 "Octal constants [...] shall not be used." How does my code get >>>>> any >>>>> better if I have to specify file permissions in hex (or with lengthy >>>>> constants)? Everyone knows what mode 0755 is. But do you know what >>>>> S_IRWXO is (without looking up the octal value)? >>>> >>>> Actually, I really *hate* the way octal is indicated in C. >>>> I much prefer the<value>r<radix> notation. It is extensible >>>> (to other radix), unambiguous, doesn't add much clutter to >>>> the code and doesn't "magically" assign extra value to things >>>> like leading zeroes. >>> >>> Agreed. But still we have that syntax and have to live with it. >> >> Yes. So, you make a *guideline* that effectively warns you >> of how you can screw yourself by using/not using a particular >> language feature, etc. "Invest in your staff", as I've said >> before. *Educate* them so they know how to write better code >> and *care* about writing better code (instead of "doing what it >> takes" to silence the policeman) > > See, I'd say that the octal constants rule is the best example of where > something that the tools will enforce coding style, rather than > guidelines to be manually enforced, is beneficial.
"Manually enforced" doesn't mean that a tool can't *detect* these things for you!
> Octal constants serve almost no purpose now that we've standardized on 8 > bit bytes. File permissions are an extremely rare exception, and can be > handled easily through something along the lines of > > #define PERMISSION(owner, group, world) (((owner) << 6) | ((group) << 3) > | (world))
Why don't we abolish hex also? Or, universally *adopt* hex (and abolish *decimal*)? Or, force anything non-decimal to be a lengthy *binary* constant? C suffers from legacy problems. Dealing with legacy codebases as well as legacy "practices". You can invent a "new C" (there have been attempts to do so) at the expense of flexibility, legacy support, etc. Continuing to support octal comes at some small cost. A "-warn_octal_constant" is just as easy to add to a compiler as a "-prohibit_octal_constant" would be. While we're at it, should we do away with %o (and %x?) conversions in printf()/scanf() et al.? And, maybe even redesign them to not use <stdarg.h>?
> Most often, if you've got a leading zero it's a mistake, not a decision > to invoke an octal. This is the sort of thing that humans are great at > missing, leading to costly debugging time, whereas compilers are great > at catching. Other examples include > > if (x == 0) > do_this(); > do_that();
Should we prohibit: while (this = count--) { ... } (note '=' not '==') Should we restrict ourselves to just *one* of the for(), while() or do-while() constructs? (personally, I use each in very different circumstances and my choice of which tells you something about the nature of the code that is encapsulated within)
> When you've got coding styles that are so easy to make mistakes with, > and offer little value, then letting the tools enforce them as > restrictions, rather than guidelines, absolutely improves reliability.
It's easy to forget to check a denominator for zero. But, you might explicitly *want* to divide by zero. If you treat it as an error, then what recourse do you have when you want to do so? How do you effect a "jump to 0x0000" if you refuse to allow a pointer to "0" to be dereferenced? Should the compiler automatically append a NUL to each "series of characters" (avoiding the use of the word "string")? All of these are "easy to make mistakes with" yet, when needed, they *do* offer value -- just not in 99.9728305% of most instances :> Personally, I live in constant fear of trigraphs screwing me over. So much so, that I deliberately force myself to avoid double question marks *anywhere*. Fortunately, this works in my favor as doubling them in anything other than a colloquial exchange is "bad style". But, I am often tempted to issue a diagnostic like: "Shirley, we can't have run out of memory so soon??!" [Thankfully, some compilers are sensitive to this sort of thing and catch my transgressions since catching them by *encountering* their unintended consequences is hard -- the diagnostic condition would have to take place for me to see the botched message!]
> I certainly don't agree with everything in the MISRA spec. But to say > that setting down hard fast rules has no value just doesn't add up.
I don't see how unilaterally *prohibiting* them buys you anything more than having a tool find them and signal them as warnings. I.e., if that tool can prohibit them, then it must know how to *find* them. Just change what the tool does in those cases. You can then choose which warnings are "deal breakers" instead of being at the mercy of whomever codified the "prohibitions". Most non-toy compilers already emit lots of useful warnings. What's a few more (, among friends :> )? Presumably, their authors -- and *users* -- see value in these as WARNINGS instead of HARD ERRORS. This, IMO, indicates that there is cause for allowing the user to determine the value of each of these "messages".
On Mon, 16 May 2011 15:41:59 -0700, D Yuniskis
<not.going.to.be@seen.com> wrote:

>Hi Stefan, > >On 5/16/2011 10:05 AM, Stefan Reuther wrote: > >> &#4294967295;7.1 "Octal constants [...] shall not be used." How does my code get any >> better if I have to specify file permissions in hex (or with lengthy >> constants)? Everyone knows what mode 0755 is. But do you know what >> S_IRWXO is (without looking up the octal value)? > >Actually, I really *hate* the way octal is indicated in C. >I much prefer the <value>r<radix> notation. It is extensible >(to other radix), unambiguous, doesn't add much clutter to >the code and doesn't "magically" assign extra value to things >like leading zeroes.
For a parser, trailing radix takes more space and slightly more effort. For the programmer, trailing radix is easier to overlook. But I agree that C's solution is unpalatable ... the compiler accepts only bases 8, 10 and 16. Using functions like strtoul() you can, in code, convert values from other bases but you have to separate the base and value and figure out what is the base yourself. I really prefer Lisp's syntax (there are 2): The simplified common syntax: #{C}{value} where C is a character - 'b' binary #b10100101 - 'o' octal #o245 - 'x' hexidecimal #xA5 or the general syntax: #{N}r{value} where N is a number, 2..36 ex: #2rb10100101 #8r245 #16rA5 YMMV, George
Rob Gaddi <rgaddi@technologyhighland.com> writes:

> On 5/17/2011 11:40 AM, D Yuniskis wrote: >> Hi Stefan, >> >> On 5/17/2011 10:11 AM, Stefan Reuther wrote: >>>>> &sect;7.1 "Octal constants [...] shall not be used." How does my code get >>>>> any >>>>> better if I have to specify file permissions in hex (or with lengthy >>>>> constants)? Everyone knows what mode 0755 is. But do you know what >>>>> S_IRWXO is (without looking up the octal value)? >>>> >>>> Actually, I really *hate* the way octal is indicated in C. >>>> I much prefer the<value>r<radix> notation. It is extensible >>>> (to other radix), unambiguous, doesn't add much clutter to >>>> the code and doesn't "magically" assign extra value to things >>>> like leading zeroes. >>> >>> Agreed. But still we have that syntax and have to live with it. >> >> Yes. So, you make a *guideline* that effectively warns you >> of how you can screw yourself by using/not using a particular >> language feature, etc. "Invest in your staff", as I've said >> before. *Educate* them so they know how to write better code >> and *care* about writing better code (instead of "doing what it >> takes" to silence the policeman) >> > > See, I'd say that the octal constants rule is the best example of > where something that the tools will enforce coding style, rather than > guidelines to be manually enforced, is beneficial. > > Octal constants serve almost no purpose now that we've standardized on > 8 bit bytes.
I use them sometimes. For example, in electronics buffers and ports tend to come in 8-bit multiples. So we have a PLC-like thing with its I/Os numbered 0500 0501 0502 0503 0504 0505 0506 0507 0510 0511 ... Etc. The I/O line number gets defined and passed around as an octal constant. Pretty rare though I agree. [...] -- John Devereux
Hi George,

On 5/17/2011 3:19 PM, George Neuner wrote:

[8<]

>> Actually, I really *hate* the way octal is indicated in C. >> I much prefer the<value>r<radix> notation. It is extensible >> (to other radix), unambiguous, doesn't add much clutter to >> the code and doesn't "magically" assign extra value to things >> like leading zeroes. > > For a parser, trailing radix takes more space and slightly more > effort. For the programmer, trailing radix is easier to overlook.
And *both* suffer from the fact that we don't *think* of the constants in terms of *any* "radix indication". I.e., to me, ASCII SP is "20" or "40", depending on "where I am". I don't think of "0x20" or "040" until I have to "write it down".
> But I agree that C's solution is unpalatable ... the compiler accepts > only bases 8, 10 and 16. Using functions like strtoul() you can, in > code, convert values from other bases but you have to separate the > base and value and figure out what is the base yourself.
But the value of different radix is in expressing constants. You want to say things like: #define FLASH 0xFFFF0000 #define SECS_PER_TIMEZONE (24*60*60/24) #define PREAMBLE "\001\040\040" instead of being *forced* into "standardizing" on a single radix. I.e., How many folks would recognize 0x15180? Or, "32"? [I miss being able to use *binary* constants (since I write lots of drivers that need to talk to I/O's)] As you force people to express things in particular ways, solely for the sake of "standardization", you obfuscate their intent and *add* bugs (at design time and/or maintenance).
On 5/18/2011 6:28 AM, D Yuniskis wrote:

> [snip] > [I miss being able to use *binary* constants (since I write lots > of drivers that need to talk to I/O's)]
You can use 0b binary constants in gcc, actually. Of course, being a compiler specific extension, this isn't supported by MISRA. -- Rob Gaddi, Highland Technology Email address is currently out of order
Hi Rob,

On 5/18/2011 9:04 AM, Rob Gaddi wrote:
> On 5/18/2011 6:28 AM, D Yuniskis wrote: > >> [snip] >> [I miss being able to use *binary* constants (since I write lots >> of drivers that need to talk to I/O's)] > > You can use 0b binary constants in gcc, actually. Of course, being a > compiler specific extension, this isn't supported by MISRA.
Yes, but it's an extension and not part of the language. I.e., not portable (won't work on HC11 compiler, etc.) In a semi-portable way, you can write an m4 macro to handle it and preprocess your source. But that just gets painful...