cURL / Mailing Lists / curl-library / Single Mail

curl-library

libcurl internal bool TRUE and FALSE definitions and usage

From: Yang Tse <yangsita_at_gmail.com>
Date: Sun, 16 Dec 2012 04:07:36 +0100

Hi friends,

The origin of all this libcurl internal bool TRUE and FALSE
definitions and usage I am bringing to your attention was triggered
due to a compilation issue on a HP-UX system reported by Frank Chang
on the mailing list.

Fact 1)

HP-UX <net/if.h> system header file indirectly includes
<sys/rw_lock.h> which in case of being used with _KERNEL not defined
either defines TRUE and FALSE or requires that these are specifically
defined to 1 and 0. For what we care we can simplify <sys/rw_lock.h>
to the following lines...

#ifndef _RW_LOCK_INCLUDED
#define _RW_LOCK_INCLUDED

#ifndef _KERNEL
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#else
#if ((TRUE != 1) || (FALSE != 0))
This is probably not a good thing....
#endif
#endif /* !TRUE */
#endif /* !_KERNEL */

#endif /* _RW_LOCK_INCLUDED */

Fact 2)

<sys/rw_lock.h> is not the only HP-UX system header file which may
define TRUE and FALSE to 1 and 0 when not defined yet, or enforce that
pre-existing definitions of TRUE and FALSE match exactly 1 and 0 when
header is included.

IOW HP-UX system header files takes ownership of TRUE and FALSE C
preprocessor macro definitions.

Fact 3)

This version of HP-UX compiler has no <stdbool.h> header file.

Fact 4)

HP-UX <rpcsvc/yp_prot.h> typedef'ines bool as unsigned int. This
Doesn't affect libcurl.

Fact 5)

HP-UX <curses_colr/curses.h> typedef'ines bool as char. This Doesn't
affect libcurl.

Fact 6)

Original issue is not a 'header inclusion order'. There is no header
inclusion ordering wich prevents HP-UX system header files from taking
ownership of TRUE and FALSE definitions.

Comment 1)

Dan Fandrich is right when he said: "I really don't think HP-UX
expects every application to have to define TRUE and FALSE macros in
order to compile."

But the fact is that if the application defines them and it happens to
include a system header which checks the definition, then the system
headers actually enforce the definition. libcurl's lib/setup_once.h
defines TRUE and FALSE macros when these aren't previously defined to
'true' and 'false'.

Additionally this system does not have <stdbool.h> and configure
script has not detected a 'bool' data type, so lib/setup_once.h
typedef'ines bool as an enum and defines appropriate 'true' and
'false'

When later on a header file such as <net/if.h> is included compilation
fails due to TRUE being defined in such a way that the preprocessor is
not capable of determining that its value is 1, and the same for FALSE
and 0.

Comment 2)

First hack allowing compilation was defining TRUE and FALSE to 1 and 0
for HP-UX systems in lib/setup_once.h even when bool has been
typedef'ed as an enum. Once more Dan Fandrich is right when calling
this 'a dreadful hack'.

The purpose of internally using the bool data type was to detect and
avoid unclever assignments to bool variables, attempting to get
compiler warnings or errors when such a condition existed.

Comment 3)

What would happen if <net/if.h> and its prerequisites were included
before libcurl's definition of TRUE and FALSE?

When _KERNEL isn't defined <sys/rw_lock.h> would define them to 1 and
0 and lib/setup_once.h would not define them. Same situation as
described in 'Comment 2' but definition taking place in a different
header.

A proper fix, but 1K+ LOC affected)

Modify libcurl to use 'private' namespace. Use 'curl_bool' instead of
'bool', CURL_TRUE instead of TRUE, CURL_FALSE instead of FALSE.

'curl_bool' could be our own enum definition only for systems which
lack 'bool' or for all.

Or something similar.

-- 
-=[Yang]=-
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
Received on 2012-12-16