Bug 2342514 - So many errors with bool in ncurses.h when compiled with clang
Summary: So many errors with bool in ncurses.h when compiled with clang
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: ncurses
Version: rawhide
Hardware: Unspecified
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Miroslav Lichvar
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 2341787
TreeView+ depends on / blocked
 
Reported: 2025-01-28 07:56 UTC by Mamoru TASAKA
Modified: 2025-01-29 03:02 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2025-01-28 11:19:38 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Mamoru TASAKA 2025-01-28 07:56:06 UTC
With:
ncurses-devel-6.5-4.20250118.fc42.x86_64
clang-19.1.7-1.fc42.x86_64

Compiling the following simple code produces errors:

```
[mockbuild@9de21fea9e68441d833bf79f25370c25 ~]$ cat conftest.c 
#include <ncurses.h>

int foo(void) { return 0; }
[mockbuild@9de21fea9e68441d833bf79f25370c25 ~]$ clang -c conftest.c
In file included from conftest.c:1:
/usr/include/ncurses.h:638:23: error: unknown type name 'bool'
  638 | extern NCURSES_EXPORT(bool) can_change_color (void);                    /* implemented */
      |                       ^
/usr/include/ncurses.h:674:23: error: unknown type name 'bool'
  674 | extern NCURSES_EXPORT(bool) has_colors (void);                          /* implemented */
      |                       ^
/usr/include/ncurses.h:675:23: error: unknown type name 'bool'
  675 | extern NCURSES_EXPORT(bool) has_ic (void);                              /* implemented */
      |                       ^
/usr/include/ncurses.h:676:23: error: unknown type name 'bool'
  676 | extern NCURSES_EXPORT(bool) has_il (void);                              /* implemented */
      |                       ^
/usr/include/ncurses.h:695:23: error: unknown type name 'bool'
  695 | extern NCURSES_EXPORT(bool) isendwin (void);                            /* implemented */
      |                       ^
/usr/include/ncurses.h:696:23: error: unknown type name 'bool'
  696 | extern NCURSES_EXPORT(bool) is_linetouched (WINDOW *,int);              /* implemented */
      |                       ^
/usr/include/ncurses.h:697:23: error: unknown type name 'bool'
  697 | extern NCURSES_EXPORT(bool) is_wintouched (WINDOW *);                   /* implemented */
      |                       ^
/usr/include/ncurses.h:828:38: error: a parameter list without types is only allowed in a function definition
  828 | extern NCURSES_EXPORT(void) use_env (bool);                             /* implemented */
      |                                      ^
/usr/include/ncurses.h:829:41: error: a parameter list without types is only allowed in a function definition
  829 | extern NCURSES_EXPORT(void) use_tioctl (bool);                          /* implemented */
      |                                         ^
/usr/include/ncurses.h:960:23: error: unknown type name 'bool'
  960 | extern NCURSES_EXPORT(bool) is_term_resized (int, int);
      |                       ^
/usr/include/ncurses.h:979:48: error: a parameter list without types is only allowed in a function definition
  979 | extern NCURSES_EXPORT(int) use_extended_names (bool);
      |                                                ^
/usr/include/ncurses.h:987:23: error: unknown type name 'bool'
  987 | extern NCURSES_EXPORT(bool) is_cleared (const WINDOW *);        /* generated */
      |                       ^
/usr/include/ncurses.h:988:23: error: unknown type name 'bool'
  988 | extern NCURSES_EXPORT(bool) is_idcok (const WINDOW *);          /* generated */
      |                       ^
/usr/include/ncurses.h:989:23: error: unknown type name 'bool'
  989 | extern NCURSES_EXPORT(bool) is_idlok (const WINDOW *);          /* generated */
      |                       ^
/usr/include/ncurses.h:990:23: error: unknown type name 'bool'
  990 | extern NCURSES_EXPORT(bool) is_immedok (const WINDOW *);        /* generated */
      |                       ^
/usr/include/ncurses.h:991:23: error: unknown type name 'bool'
  991 | extern NCURSES_EXPORT(bool) is_keypad (const WINDOW *);         /* generated */
      |                       ^
/usr/include/ncurses.h:992:23: error: unknown type name 'bool'
  992 | extern NCURSES_EXPORT(bool) is_leaveok (const WINDOW *);        /* generated */
      |                       ^
/usr/include/ncurses.h:993:23: error: unknown type name 'bool'
  993 | extern NCURSES_EXPORT(bool) is_nodelay (const WINDOW *);        /* generated */
      |                       ^
/usr/include/ncurses.h:994:23: error: unknown type name 'bool'
  994 | extern NCURSES_EXPORT(bool) is_notimeout (const WINDOW *);      /* generated */
      |                       ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
```

gcc-15.0.1-0.4.fc42.x86_64 does not produce the above errors,
however maybe gcc is "kind" enough to take care of the above,
and anyway maybe "ncurses.h" have to do include stdbool.h or some other.

Reproducible: Always

Comment 1 Mamoru TASAKA 2025-01-28 07:56:53 UTC
F41 ncurses-devel-6.5-2.20240629.fc41.x86_64 does not seem to reproduce this error.

Comment 2 Mamoru TASAKA 2025-01-28 08:13:13 UTC
Also, with ncurses-devel-6.5-4.20250118.fc42.x86_64

```
#include <stdbool.h> 
#include <ncurses.h>

int foo(void) { return 0; }
```
compiles with clang-19.1.7-1.fc42.x86_64

Comment 3 Thomas E. Dickey 2025-01-28 08:49:23 UTC
I suppose ncurses.h needs a clang-specific include to handle the case
where ncurses is configured with gcc and then used with other compilers.

(configuring with clang worked for my test-builds)

Comment 4 Thomas E. Dickey 2025-01-28 09:05:05 UTC
I hadn't noticed that (though I have noticed other bugs in both compilers).
In a quick check, I see this difference between the two configurations:

--- curses.h	2025-01-28 04:00:11.691991819 -0500
+++ gcc-curses.h	2025-01-28 03:59:02.000000000 -0500
@@ -109,7 +109,7 @@
  * User-definable tweak to disable the include of <stdbool.h>.
  */
 #ifndef NCURSES_ENABLE_STDBOOL_H
-#define NCURSES_ENABLE_STDBOOL_H 1
+#define NCURSES_ENABLE_STDBOOL_H 0
 #endif
 
 /*
@@ -285,7 +285,7 @@
 
 typedef unsigned char NCURSES_BOOL;
 
-#if defined(__cplusplus)	/* __cplusplus, etc. */
+#if 0	/* __cplusplus, etc. */
 
 /* use the C++ compiler's bool type */
 #define NCURSES_BOOL bool
@@ -296,7 +296,7 @@
 #include <stdbool.h>
 /* use whatever the C compiler decides bool really is */
 #define NCURSES_BOOL bool
-#elif !defined(__cplusplus) && !0
+#elif !defined(__cplusplus) && !1
 /* there is no predefined bool - use our own */
 #undef bool
 #define bool NCURSES_BOOL

Comment 5 Thomas E. Dickey 2025-01-28 09:05:34 UTC
I hadn't noticed that (though I have noticed other bugs in both compilers).
In a quick check, I see this difference between the two configurations:

--- curses.h	2025-01-28 04:00:11.691991819 -0500
+++ gcc-curses.h	2025-01-28 03:59:02.000000000 -0500
@@ -109,7 +109,7 @@
  * User-definable tweak to disable the include of <stdbool.h>.
  */
 #ifndef NCURSES_ENABLE_STDBOOL_H
-#define NCURSES_ENABLE_STDBOOL_H 1
+#define NCURSES_ENABLE_STDBOOL_H 0
 #endif
 
 /*
@@ -285,7 +285,7 @@
 
 typedef unsigned char NCURSES_BOOL;
 
-#if defined(__cplusplus)	/* __cplusplus, etc. */
+#if 0	/* __cplusplus, etc. */
 
 /* use the C++ compiler's bool type */
 #define NCURSES_BOOL bool
@@ -296,7 +296,7 @@
 #include <stdbool.h>
 /* use whatever the C compiler decides bool really is */
 #define NCURSES_BOOL bool
-#elif !defined(__cplusplus) && !0
+#elif !defined(__cplusplus) && !1
 /* there is no predefined bool - use our own */
 #undef bool
 #define bool NCURSES_BOOL

Comment 6 Thomas E. Dickey 2025-01-28 09:06:38 UTC
(bugzilla flagged a collision above...)

Comment 7 Miroslav Lichvar 2025-01-28 09:28:09 UTC
Thanks.

I think the simplest solution for us is to change NCURSES_ENABLE_STDBOOL_H to 1 in the generated ncurses.h. That seems to work with both gcc15 and clang.

Comment 8 Daniel Berrangé 2025-01-28 10:16:48 UTC
Note, this isn't just a bug wrt to CLang, it affects GCC too, depending on the standard you compile against:

 * In GCC 14, the default was -std=gnu18 where use of stdbool.h was required.
 * In GCC 15, the default is now -std=gnu23 where stdbool.h is obsolete (but harmless to still use), as 'bool' is a built-in type.

The ncurses build script has run without any -std arg AFAICS and thus has seen 'bool' as a built-in and thus turned off use of stdbool.h in the ncurses.h header:

https://kojipkgs.fedoraproject.org/packages/ncurses/6.5/4.20250118.fc42/data/logs/x86_64/build.log

  checking if we should include stdbool.h... no
  checking for builtin bool type... yes

Compare to the previous buld against GCC 14

https://kojipkgs.fedoraproject.org/packages/ncurses/6.5/2.20240629.fc41/data/logs/x86_64/build.log

  checking if we should include stdbool.h... yes
  checking for builtin bool type... no

The result is that any application built with GCC 15 which sets a -std arg less than gnu23, is now broken, as they won't have 'bool' as a built-in while ncurses.h has disabled stdbool.h.

IMHO, ncurses configure checks are wrong. If it detects that stdbool.h exists on a system, it should *always* use it in ncurses.h, regardless of whether 'bool' is a built-in or not.

> I think the simplest solution for us is to change NCURSES_ENABLE_STDBOOL_H to 1 in the generated ncurses.h. That seems to work with both gcc15 and clang.

Another option is possibly to set -std=gnu18 in the spec, eg

diff --git a/ncurses.spec b/ncurses.spec
index 74c921a..a0d142f 100644
--- a/ncurses.spec
+++ b/ncurses.spec
@@ -129,6 +129,7 @@ for f in ANNOUNCE; do
 done
 
 %build
+CFLAGS="$CFLAGS -std=gnu18"
 common_options="\
     --enable-colorfgbg \
     --enable-hard-tabs \

Comment 9 Miroslav Lichvar 2025-01-28 11:19:38 UTC
It should be now fixed in ncurses-6.5-5.20250125.fc42.


Note You need to log in before you can comment on or make changes to this bug.