Keith Thompson said:
Yevgen Muntyan said:
CBFalconer wrote:
Yevgen Muntyan wrote:
... snip ...
The following code doesn't compile with "gcc foo.c":
#include <stdbool.h>
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
typedef enum { false, true } bool;
#endif
int main (void)
{
return 0;
}
See the stdops.h header below. You should also test for __STDC__.
Use -W -Wall -ansi -pedantic with gcc.
[snip]
It (namely the code below) suffers from the very same problem.
__STDC_VERSION__ gets defined only if you use -std=c99, when it's
pointless. -ansi doesn't make it work.
--------------------------------------------------
#include <stdbool.h>
#ifndef stdops_h
#define stdops_h
#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
/* The following from C99 - must define for C90 */
#include <stdbool.h> /* define bool, true, false */
#include <iso646.h> /* define not, and, or */
#else
#define false 0
#define true 1
typedef int bool;
#define not !
#define and &&
#define or ||
#define xor ^
#endif
#endif
int main (void)
{
}
Right. If you add an unconditional "#include <stdbool.h>" to code
that carefully tests whether C99 is supported, it will break if
compiled in non-C99 mode. So don't do that.
I think there's a real potential problem here that I haven't been
taking seriously enough.
The fact is, C99 conformance is not (currently) an all-or-nothing
thing. A number of implementations support some, but not all, C99
features. In particular, an implementation can support <stdbool.h>,
and possibly the _Bool keyword, without setting __STDC_VERSION__ to
indicate C99 conformance. This is probably even a reasonable thing to
do while working on full conformance.
For code written to work under such an implementation, it's likely
that some separately developed part of the program, such as a library
header will have a "#include <stdbool.h>" header. Since <stdbool.h>
defines false, true, and bool as macros, this can conflict with code
that attempts to define the same identifiers.
I think that adding #undef directives before attempting to define
these identifiers should fix at least part of the problem. Defining
them in a way as close to what <stdbool.h> does as possible is
probably also a good idea.
For example:
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
#undef false
#undef true
#undef bool
#define false 0
#define true 1
#define bool int
#endif
All this can be put into a header file, say "mystdbool.h".
There *could* still be problems if the third-party code that uses
<stdbool.h> depends on attributes of _Bool (or bool) that don't apply
to int, such as the fact that converting any non-zero value to bool
yields 1.