MISRA Rule 10.4 Violation - c

I'm getting the next MISRA error:
Rule-10.4 The operands of this equality operator are expressions of different 'essential type' categories (Boolean and unsigned).
The code is showed below:
#define TRUE (1!=0)
#define FALSE (0!=0)
typedef unsigned char boolean;
boolean active;
getActive(&active);
if (TRUE == active) <<<<<<<<<<<< HEre is the conflicting line
{
// DO Something
}
If I remove the TRUE :
if (active)
MISTA Rule 14.4 appears: "Controlling expression is not an 'essentially Boolean' expression"
So I cannot figure out the solution,
I see that using
#define TRUE 1U
#define FALSE 0U
solves the problem but I'm afraid I cannot afford this solution since I'm using a big inherited code from a 3rd party using the (1!=0) expression.
I guess that expression is more 'smart' and portable since in some systems the meaning of TRUE/ FALSE might chenge to 0/1 but I wonder if I can keep the:
#define TRUE (1!=0)
#define FALSE (0!=0)
and write my conditional expressions in a manner to cope with the MISRA issues

Your MISRA checker is unable to determine that these are your boolean type.
In case you are stuck with C90 and only then: you need to inform your tool somehow about which custom bool type you are using. Otherwise it won't be able to tell what these macros are for.
Otherwise, simply use stdbool.h. There are very few excuses not to in the year 2019.

Thanks to all for the answers and comments.
Unfortunately I'm not allowed to use stdbool.h , I'm using an AUTOSAR (automotive) stack and they don't use any of the standard libraries.
I'd prefer don't to trick the MISRA tool to indicate the boolean type, I thinkit would be something that we'd have to export to any PC of the team (ad-hoc solution)
Thanks to #R about the (1 != 0) clarification; it makes no sense , C is C (not bash or whatever where the true might be 0) , and true will be always 1, so unless you are ignorant about the bool value in your programming language the definition as a expression is useless.
I think that for my porpuses the best solution would be to redefine the macros as:
#define TRUE (1U)
#define FALSE (0U)
I've seen the AUTOSAR stack gives me the option to redefine this values in a Integration file
And this way I keep the compatibility with all my Application code and the existing AUTOSA stack and also I don't need to change anything in the inherited code.

Related

Why is 'bool' keyword syntax highlighted in Xcode configured for C89?

I read that booleans in C first came with C99. Now I wonder why bool nevertheless gets colored by Xcode's syntax highlighting, or what you call it...
When one searches "dial" in the build settings in Xcode, the "Language Dialect" pops up, and there I "dial-in" the C89 standard, and still bool gets colored.
Why is that?
I also read this:
Using boolean values in C
and I see how they did it, but I also don't understand how Example 3 and 4 works...
Option 3
typedef int bool;
enum { false, true };
Option 4
typedef int bool;
#define true 1
#define false 0
Note: I don't understand how the typedef int bool; could in anyway be connected with the line enum { false, true };.
Why is xcode with C89 not ignoring the bool keyword?
How do the examples work?
The syntax highlighting is an approximation used by XCode; it's not guaranteed to follow any standard. Not to say the syntax highlighting in XCode is not fairly advanced, but it would be very difficult to tell without compiling for a specific standard, what the symbols mean exactly, in real-time.
In the case of Option 3, it's performing an implicit conversion from an anonymous enum to an int. Since they are compatible types, it is "always a no-op and does not change the representation." The default enum values for { false, true } are { 0, 1 }, so this should result in the same assembler output. This answer has the order of preference when one doesn't know what to pick.

Why use <stdbool.h> instead of _Bool?

Any time I had the need of a Boolean type I was told to either create one, or better yet, use stdbool.h.
Since stdbool.h uses typedef bool _Bool, is there a reason to use the header instead just using type _Bool? Is it just for the additional macros (/* #define true 1 #define false 0 */)?
The obvious type to add into the language was bool. But unfortunately, plenty of code was written that included bool in other shapes and forms. Recall that support for a boolean type was added only in C99.
So the C language committee had no choice but to pull out a reserved identifier for it (_Bool). But, since the obvious choice of type name is still the same, stdbool.h was added to allow users the obvious name. That way, if your code didn't have a home-brewed bool, you could use the built in one.
So do indeed use stdbool.h if you aren't bound to some existing home-brewed bool. It will be the standard type, with all the benefits that type brings in.
The common practice has always been to use bool but when the type was officially introduced into the standard in C99, they didn't want to break the "roll-your-own" implementations. So they made the type _Bool as kind of a hack around the unofficial bools. Now there's no type name collision. Anyway, point is, use bool unless a legacy codebase breaks.
They are same. bool is an alias for _Bool.
Before C99 we used we dont have this type. (Earlier the use was limited to an integer tyoe with 0 as false and 1 as true).
You may not use it. Even you can undef bool (but it is recommended not to do so). But including it (stdbool.h and bool alias of _Bool) is good because then if someday it becomes reserved your code complies to that.1
1. You can use bool other way but it is better not to. Because in general when this stdbool.h is introduced it bears the plan of gradually making it standard and then even more stricter rule applies where we can't use bool as something other and it will be reserved as keyword.

Does MISRA C 2012 say not to use bool

I am in the early stages of framing stuff out on a new project.
I defined a function with a return type of "bool"
I got this output from PC-Lint
Including file sockets.h (hdr)
bool sock_close(uint8_t socket_id);
^
"LINT: sockets.h (52, 1) Note 970: Use of modifier or type '_Bool' outside of a typedef [MISRA 2012 Directive 4.6, advisory]"
I went ahead and defined this in another header to shut lint up:
typedef bool bool_t;
Then I started wondering why I had to do that and why it changed anything. I turned to MISRA 2012 Dir 4.6. It is concerned mostly about the width of primitive types like short, int, and long, their width, and how they are signed.
The standard does not give any amplification, rational, exception, or example for bool.
bool is explicitly defined as _Bool in stdbool.h in C99. So does this criteria really apply bool?
I thought _Bool was explicitly always the "smallest standard unsigned integer type large enough to store the values 0 and 1" according to section 6.2.5 of C99. So we know bool is unsigned. Is it then just a matter of the fact that _Bool is not fixed width and subject being promoted somehow that's the issue? Because the rational would seem to contradict that notion.
Adherence to this guideline does not guarantee portability because the size of the int type may determine whether or not an expression is subject to integer promotion.
How does just putting typedef bool bool_t; change anything - because I do nothing to indicate the width or the signdedness in doing so? The width of bool_t will just be platform dependent too. Is there a better way to redefine bool?
A type must not be defined with a specific length unless the implemented type is actually of that length
so typedef bool bool8_t; should be totally illegal.
Is Gimpel wrong in their interpretation of Directive 4.6 or are they spot on?
Use of modifier or type '_Bool' outside of a typedef [MISRA 2012 Directive 4.6, advisory]
That's nonsense, directive 4.6 is only concerned about using the types in stdint.h rather than int, short etc. The directive is about the basic numerical types. bool has nothing to do with that directive whatsoever, as it is not a numerical type.
For reasons unknown, MISRA-C:2012 examples use a weird type called bool_t, which isn't standard. But MISRA does by no means enforce this type to be used anywhere, particularly they do not enforce it in directive 4.6, which doesn't even mention booleans. MISRA does not discourage the use of bool or _Bool anywhere.
Is Gimpel wrong in their interpretation of Directive 4.6
Yes, their tool is giving incorrect diagnostics.
In addition, you may have to configure the tool (if possible) to tell it which bool type that is used. 5.3.2 mentions that you might have to do so if not using _Bool, implying that all static analysers must understand _Bool. But even if the bool type is correctly configured, dir 4.6 has nothing to do with it.
A potential concern with Boolean types is that a lot of code prior to C99 used a single-byte type to hold true/false values, and a fair amount of it may have used the name "bool". Attempting to store any multiple of 256 into most such types would be regarded as storing zero, while storing a non-zero multiple of 256 into a c99 "bool" would yield 1. If a piece of code which uses a C99 "bool" is ported into a piece of code that uses a typedef'ed byte, the resulting code could very easily malfunction (it's somewhat less likely that code written for a typedef'ed byte would rely upon any particular behavior when storing a value other than 0 or 1).

C doesn't have a bool? Also VS2010 question

I'm using VS 2010 Pro.
First, C doesn't have a bool type? I just have to use int with 0/1. Seems odd as most languages consider boolean a standard type.
Also I have Visual Studio 2010 Pro but doesn't have a "C Project". I just created an Empty C++ Project. The file names end with .c
The problem with this is the keywords are messed up (shows bool as highlighted/valid in the editor, but compiler doesn't like it).
I went to repair/add components and they have C#, F#, C++, Visual Basic; but no C?
Newest C standard (C99) has bool type indeed. Just include stdbool.h and you can use it. Unfortunately MSVC does not haver proper support for C at all. Only partial C89.
The current C language (C99) has a bool type (actually _Bool, but including stdbool.h declares a typedef alias bool for it), but since you're using MSVC, that's not available to you. In any case, using boolean types in C is completely non-idiomatic and largely useless. Just use int like everyone else. Or if you need a giant array of them, make your own bit-array implementation.
C did not have an actual Boolean type until C99.
As a result, idiomatic C doesn't really use boolean-valued symbols or expressions as such (i.e., you won't see many explicit tests against "true" or "false"). Instead, any zero-valued integral expression or a NULL pointer will evaluate to "false", and any non-zero-valued integral expression or a non-NULL pointer will evaluate to "true". So you'll see a lot of code like:
foo *bar = malloc(sizeof *bar * ...);
if (bar) // equivalent to writing bar != NULL
{
// bar is non-NULL
}
Relational and equality expressions such as a == b or c < d will evaluate to an integral type with a value of either 1 (true) or 0 (false).
Some people introduce their own TRUE or FALSE symbolic constants by doing something like
#define TRUE (1) // or (!FALSE), or (1==1), or...
#define FALSE (0) // or (!TRUE), or (1==0), or ...
Unforunately, some of those people occasionally manage to misspell 0 or 1 (or the expressions that are supposed to evaluate to 0 or 1); I once spent an afternoon chasing my tail because someone screwed up and dropped a header where TRUE == FALSE.
Not coincidentally, that was the day I stopped using symbolic constants for Boolean values altogether.
See R.'s answer for information about the bool type.
Unfortunately, MSVC doesn't support C99 when it's compiling C code - it has bits and pieces (generally things in the C99 library that are required by C++), but for the most part it only supports C90.
As for bool still being highlighted in the editor - the highlighting in MSVC may be sophisticated, but it doesn't take into account the differentiation between C, C++, and C++/CLI. For example, if you use a construct that's CLI-only, it'll be highlighted as such even if your project has nothing to do with CLI.
If you're developing in C, I'd recommend a different compiler as VC++ is not a modern C compilier and does not support the C99 standard. If you're on windows try MinGW, which basically gets you GCC with access to Windows-y API stuff.
If you're set on using Visual Studio, create your own header file to use instead of stdbool.h:
#pragma once
#define false 0
#define true 1
#define bool int
I found that Visual Studio 2010 complained if I tried to use a typedef instead of a #define to define bool.
Concerning the bool type:
In C, any non-zero value is regarded as "true" (and zero is "false"). This comes in handy when, say, checking the value of a pointer:
if ((ptr = malloc(sizeof(foo))) != 0) ...
can be shortened to:
if (ptr = malloc(sizeof(foo))) ...
C was designed to be a "mid-level" language, i.e. in-between assembler and traditional "high-level" languages. It was also designed to be compact/concise. So it has a minimalist flavor, exemplified in the its support for "shorthand" like the above, and also in the omission of a built-in Boolean data type (up to C99, as others have pointed out).
Many libraries/frameworks (ones that I'm aware of anyway) do something like the following
#define BOOL int
#define FALSE 0
#define TRUE (!FALSE)
This does mean that you should avoid directly comparing values/results to TRUE. Consider the following. Given int a = 2; int b = 3;, then both if (a) and if (b) evaluate to true, but a and b are not equal.
Concerning syntax highlighting:
C++ does have a bool type, which I'm guessing is why the compiler highlights the word. However, the fact that your source file ends it .c marks it as C code, so the type isn't allowed.
Seems like the syntax highlighting should catch this, though.
Concerning the absence of C components:
If I understand the question correctly: the short answer is, in order to do "managed code" (ie .NET) development -- which is what you'd have to be doing in order to use .NET components -- you need to use a language supported by the .NET runtime, i.e. C#, VB(.NET), F#, or C++.
(C++ is available in both "managed" and "unmanaged" flavors, meaning you can develop either against .NET or the Windows API.)
Are you under some sort of directive to use C as opposed to other languages?

Is using char as a bool in C bad practice?

Is there any downside to using
typedef char bool;
enum boolean { false, true };
in C to provide a semantic boolean type?
In C99, you should be using stdbool.h, which defines bool, true, and false.
Otherwise what you have is fine. Using just the enum may be a bit simpler, but if you really want to save space what you have works.
The short answer is: it's fine. It's particularly good if you needed to make large arrays of them, although I would be tempted to just use the C99 built-in1.
Since you asked "is there any downside..." I suppose I could remark that there have been important machines that did not actually have a character load instruction. (The Cray and initial DEC Alpha come to mind.) Machines in the future may suddenly go all minimal once again.
It will always be fast to load a standard integral type.
It will probably always be fast to load a single character.
1. See C99 6.2.5. There is a built-in type _Bool. Then, if you include <stdbool.h> (see C99 7.16) you get an alias, the more gracefully named bool, and defines for true and false. If you use this it will clash with your typedef but I'm sure it would be an easy thing to fix.
The downside of typedef char bool; is that if you compile with a C99 implementation and happen to include <stdbool.h>, this ends up as typedef char _Bool;, which is wrong. Also, if you ever tried to compile the code as C++, you'd have issues (that's not necessarily a problem, but it could be).
It would probably better either to use <stdbool.h> if your implementation provides one or to use a different name for the type, like BOOL.
I would suggest using a bit to represent true or false, rather than a character. A character uses 8 bits, We can set 1 for true and 0 for false with just 1 bit. That will be more memory efficient and also satisfies the purpose. (e.g) char flag:1;
Reference : http://en.wikipedia.org/wiki/Bit_field

Resources