I have a double type bool so have added to a header:
typedef double bool;
extern bool true;
extern bool false;
with:
bool true = 1.0;
bool false = 0.0;
in the corresponding C file.
However I now have the errors multiple definition of true, and the same for false, pointing to the first line of the first function in the C file. the error that says 'previous declaration was here' points to the same line... it doesnt make any difference which function is placed first in the file it always points to it.
My header files, though included via a common header file, do have include guards so I hopefully shouldn't have multiple declaration of true and false there.
I have changed the typedef to tBool with vars tTrue and tFalse, which solves the problem, but I don't get why it occurred in the first place? As there are still some bool types using true and false in the code it seems like the compiler may have a definition for true and false as ints already... though I didn't think C did this
Im using dev-c++ 4.9.9.2 IDE that uses mingw, though Im not sure which version mingw.
Anyone know why this happened?
It sounds to me like your parameter is not really a Boolean value at all. You have a floating point parameter with special cases for the discrete numbers 0.0 and 1.0. Create two double constants instead of a type.
C99 added definitions for the type _Bool, a macro bool, a macro true, and a macro false. Try inserting the following in your header:
#if __bool_true_false_are_defined
# error "stdbool.h has been included"
#endif
#ifdef bool
# error "bool is already DEFINED"
#endif
#ifdef true
# error "true is already DEFINED"
#endif
#ifdef false
# error "false is already DEFINED"
#endif
If any of these fire, then you are including stdbool.h somewhere. You should be able to #undef the three macros and then set up your types safely. Of course, this will probably break if someone else expects bool to be a small integer value and has more style problems that you can shake a stick at.
ISO/IEC 9899:1999 does make a concession to the fact that many groups have already defined their own Boolean types before it was added to the Standard. This is the rationale for defining bool, true, and false as macros instead of new keywords. However, the following warning is explicitly included:
7.26.7 Boolean types and values <stdbool.h>
The ability to undefine and then perhaps redefine the macros bool, true, and false is an obsolescent feature.
Related
What does the <stdbool.h> do when using it in a C code?
I searched for it on the Wikipedia and didn't get answers in my language, i would love that someone will explain to me what it means.
When the C Standard Committee finally added support for a boolean type in the C language in 1999 (C99), they did not want to create incompatible changes in the language semantics, thus they did not make bool, true and false new keywords that would have caused errors in programs already using these identifiers for types or variables, they only added the _Bool keyword for the boolean type, which was already a reserved identifier.
Yet to make these words available for new programs with standard semantics, they also added a new standard header file <stdbool.h> with this specification:
7.18 Boolean type and values <stdbool.h>
1 The header <stdbool.h> defines four macros.
2 The macro
bool
expands to _Bool.
3 The remaining three macros are suitable for use in #if preprocessing directives. They are
true
which expands to the integer constant ((_Bool)+1u),
false
which expands to the integer constant ((_Bool)+0u), and
__bool_true_false_are_defined
which expands to the integer constant 1.
4 Notwithstanding the provisions of 7.1.3, a program may undefine and perhaps then redefine the macros bool, true, and false.
I you want to use boolean variables in your program, include the <stdbool.h> header file, declare them with the bool type and use true and false as constant values.
Note that the phrase macros are suitable for use in #if preprocessing directives is achieved using a trick: true is defined as ((_Bool)+1u), not ((_Bool)1u) so #if true expands to #if ((_Bool)+1u), which ultimately expands to #if ((0)+1u) hence defines a block of source code to be compiled, whereas #if ((0)1u) would have cause a preprocessor error.
I have gone through the Wikipedia page linked above and over there it says this header file was introduced to C in the year 1999.
What I think is may be at that time we could not use the bool or true or false keywords as we are able to use now.
May be to use them at that time we would have had to include that header file
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.
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.
I am trying to compile a usb loopback example for STM32 using arm-none-eabi-gcc but am stuck on a compiler error for bool variables. The error is error: expected ';', identifier or '(' before '_Bool' and the offending lines are
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
bool;
From what I've read, it seems bool is an alias for _Bool while gcc transitions to bool being an actual type. Unfortunately I have no idea how to fix this. With some googling I've read that similar problems are sometimes related to having TRUE and FALSE defined elsewhere but I'm using largely unchanged code from STM and don't know of anywhere else they might be defined. I've also read that it could be due to linking against libc but get the same error when compiling with -nostdlib. Is there anything I can do to narrow down this problem? Thanks.
Since this typedef was trying to define a bool type and my compiler was trying to use the _Bool type, what I ended up doing was commenting out the typedef all together and just using
#define TRUE 1
#define FALSE 0
I'm not positive this solved the problem since I still can't get the usb device to enumerate, but the program now compiles.
I have code for bool typedef
typedef enum bool {
false,
true,
} bool;
in two headers files if it is not included in the ultimate parent header file, child C files cannot, of course, use type bool, though children of the lesser header file that also defines it can.
However if I define it in the ultimate parent header file then the lesser header file definition errors with "bool has already been declared in the current scope"
I need a solution for the lesser header where it may be included on a project that may or may not have already defined bool... What is the best way to do this??
Ta
First of all, if you're working with a C99 compiler or later, there's already a standard Boolean type defined in stdbool.h.
Secondly, you can usually avoid testing against true and false values directly, and I've found over the years that this actually leads to code that's a little easier to read and less error-prone (that's just a personal opinion, though -- YMMV).
The immediate solution is to surround your typedefs with an include guard:
#ifndef BOOL_DEFINED
#define BOOL_DEFINED
typedef enum bool {
false,
true
} bool;
#endif
This will keep the type from being declared more than once. However, as you've discovered, putting the same type definition in two different headers is a recipe for heartburn. It would be better to put the definition in its own header file (with the include guards as shown above), and then include that file where necessary.
I'd factor this and any other shared definitions out into a types.h header which is included by each of your other headers.
Alternatively, you could do something like
#ifndef BOOL_DEFINED
#define BOOL_DEFINED
typedef enum bool {
false,
true,
} bool;
#endif
in both headers.