M
mathog
I just found out the hard way that the C99 "bool" type can result in
some very hard to diagnose bugs. This problem came up in the context of
a field in a structure which had been declared in a file "long ago and
far away" and which I had not seen. From the usage in the file where
the problem was found it looked like this value was an int, but it was a
bool. As it turns out at least the gcc compiler (4.4.1) gives no
warnings when bools are used in ways that are "int" like but make little
or no sense for a bool.
Example code showing some of these issues:
/* testbool.c */
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
void main(void){
bool avar;
avar=1;
(void) fprintf(stdout,"avar = %d\n",avar);
avar=2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar+=2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar &= 2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar=2;
if(avar==2){
(void) fprintf(stdout,"avar == 2\n");
}
else {
(void) fprintf(stdout,"avar != 2\n");
}
}
# gcc -Wall -std=c99 -o testbool testbool.c
testbool.c:5: warning: return type of 'main' is not 'int'
# ./testbool
avar = 1
avar = 1
avar = 1
avar = 0
avar != 2
To my mind the only two of these statements that make sense as operators
on a bool are "=1" and "=2", both setting the bool to 1 (true), and the
second one only if
bool_variable = int_variable;
is always automatically converted to
bool_variable = (bool) int_variable;
The rest of them make little or no sense for an operation on a bool, yet
the compiler gives not a hint of a problem. For instance, there is no
point, ever, in incrementing a bool by 2 since the most it can change is
by 1. Similarly logic on any but the lowest bit is pointless since they
will never be set. Finally, the test "avar == 2" really should trigger
a warning since a bool can never be 2, and the 2 is not automatically
promoted to a bool (maybe the bool is promoted to an int?) In any case
the test is clearly a programming error since it can never be true, and
the compiler can know that without having to reference any other piece
of code. Seems to me that if this does not generate a warning then the
compiler should be doing it the other way around, consider the "2" as a
bool, thus true, and the result should be True. (Which it isn't.)
What exactly are the rules for bool such that the behavior shown above
all makes sense (and is not worthy of a compiler warning)?
Thanks,
David Mathog
some very hard to diagnose bugs. This problem came up in the context of
a field in a structure which had been declared in a file "long ago and
far away" and which I had not seen. From the usage in the file where
the problem was found it looked like this value was an int, but it was a
bool. As it turns out at least the gcc compiler (4.4.1) gives no
warnings when bools are used in ways that are "int" like but make little
or no sense for a bool.
Example code showing some of these issues:
/* testbool.c */
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
void main(void){
bool avar;
avar=1;
(void) fprintf(stdout,"avar = %d\n",avar);
avar=2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar+=2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar &= 2;
(void) fprintf(stdout,"avar = %d\n",avar);
avar=2;
if(avar==2){
(void) fprintf(stdout,"avar == 2\n");
}
else {
(void) fprintf(stdout,"avar != 2\n");
}
}
# gcc -Wall -std=c99 -o testbool testbool.c
testbool.c:5: warning: return type of 'main' is not 'int'
# ./testbool
avar = 1
avar = 1
avar = 1
avar = 0
avar != 2
To my mind the only two of these statements that make sense as operators
on a bool are "=1" and "=2", both setting the bool to 1 (true), and the
second one only if
bool_variable = int_variable;
is always automatically converted to
bool_variable = (bool) int_variable;
The rest of them make little or no sense for an operation on a bool, yet
the compiler gives not a hint of a problem. For instance, there is no
point, ever, in incrementing a bool by 2 since the most it can change is
by 1. Similarly logic on any but the lowest bit is pointless since they
will never be set. Finally, the test "avar == 2" really should trigger
a warning since a bool can never be 2, and the 2 is not automatically
promoted to a bool (maybe the bool is promoted to an int?) In any case
the test is clearly a programming error since it can never be true, and
the compiler can know that without having to reference any other piece
of code. Seems to me that if this does not generate a warning then the
compiler should be doing it the other way around, consider the "2" as a
bool, thus true, and the result should be True. (Which it isn't.)
What exactly are the rules for bool such that the behavior shown above
all makes sense (and is not worthy of a compiler warning)?
Thanks,
David Mathog