Why does C use the word _Bool to define boolean values? Whereas they use the word float for floats and not _Float?
Furthermore, why does bool have to be included, why isn't part of the basic functionality, like float?
_Bool was not originally in C, but was added in the 1999 C Standard. If it had been called bool then a large amount of existing code would break because many projects made their own type alias bool already.
The C89 standard set aside identifiers starting with _ followed by upper-case character as reserved for implementation use. This is why new features added to C always start with such names. _Complex, _Alignof and _Static_assert are other examples.
There is also a header <stdbool.h> which aliases bool to _Bool and defines true and false ; this header can be included by new projects or by projects that didn't already define bool.
C did not originally have a Boolean type, it was added in the 1999 version of the language (C99). At that point, C++ was already standardized (in 1998) to use the type bool, with keywords false and true. To keep the C Boolean type separate from the one in C++, as well as preventing the new name from breaking old C code, it was named _Bool.
The reason why it was named with an underscore followed by an upper-case letter, is because such an identifier was already guaranteed not to exist in compiler, library or user code, by 7.1.3:
All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
"Reserved for any use" meaning reserved for future versions of the C language.
Therefore, all new language keywords that have been added to the language since C99 are named with underscore followed by first letter upper-case. Other examples from C99 are the types _Complex and _Imaginary.
For the cases where code compatibility with C++ was desired, the header <stdbool.h> was created. It contains the macro bool, which expands to _Bool. And also the macros false and true that expand to 0 and 1.
Though note that booleans are not fully integrated in the C language, as they are in C++. In C++, an expression such as a == b gives a result of type bool, with the value true or false. In C it gives a result of type int, with the value 1 or 0. This is for backwards-compatibility reasons with old C code.
As for ...
Furthermore, why does bool have to be included, why isn't part of the
basic functionality, like float?
... I observe that although you need to include stdbool.h to get bool, that's a convenience and C++-compatibility feature, not an essential. bool is an alias for _Bool, and in C99 and later you have _Bool automatically, but even that is non-essential. In C, any integer or pointer value can be interpreted as a boolean, with 0 or NULL being interpreted as false and all other values being interpreted as true. This was how boolean values were handled in C from the beginning, and it still works in implementations conforming to the latest standard.
In fact, type _Bool itself is just a special case of this very behavior: it is an integer type whose minimal requirements are that it be able to represent the values 0 and 1. In boolean context, it works just the same as any other integer type.
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
The C11 spec on enums1, states that the enumerator constants must have type int (1440-1441):
1440 The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
1441 The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.107)
However, it indicates that the backing type of the enum can be either a signed int, and unsigned int, or a char, so long as it fits the range of constants in the enum (1447-1448):
1447 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type.
1448 The choice of type is implementation-defined,108) but shall be capable of representing the values of all the members of the enumeration.
This seems to indicate that only the compiler can know the width of an enum type, which is fine until you consider an array of enum types as part of a dynamically linked library.
Say you had a function:
enum my_enum return_fifth(enum my_enum[] lst) {
return lst[5];
}
This would be fine when linked to statically, because the compiler knows the size of a my_enum, but any other C code linking to it may not.
So, how is it possible for one C library to dynamically link to another C library, and know how the compiler decided to implement the enums? (Or do most modern compilers just stick with int/uint and forgo using chars altogether?
1Okay, I know this website is not quite the C11 standard, where as this one is a bit closer: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
C standard doesn't says anything about dynamical library or even static library, these concepts doesn't exist in standard. This is in the implemented behavior domain.
But as you said nothing prevent a compiler to use different type for an enumeration, this mean the one compiler can use a type and another use a different type.
This would be fine when linked to statically
In fact no, let say that A is a compiler that used char and B is a compiler that used int, and let say these types are not the same size. You compile a static library with the A compiler, and you statically link this library to a program compiled by B. This is static and still, B can't know that A doesn't use the B type for the enum.
So, how is it possible for one C library to dynamically link to another C library
Well, as I said this is not possible for static library, for the same reason, this is not possible for dynamic library.
Or do most modern compilers just stick with int/uint and forgo using chars altogether?
Big compiler generally talk between them to use the same rules on the same environment, yes. But nothing in C guaranty this behavior. (On the compatibility problem: a lot of people use "The C ABI", despite the fact it doesn't exist in the standard.)
So the best advice is to compile your dynamic library with the same compiler and option that compile your main program, also check the documentation of your compiler is a big plus.
The complete definition of the enum needs to be visible at the time it is used. Then the compiler will know what the size will be.
Forward declarations of enum types is not allowed.
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.
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).
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?