www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/02/02/16:35:12

Message-Id: <3.0.6.32.19990202114413.009062c0@pop.netaddress.com>
X-Sender: pderbysh AT pop DOT netaddress DOT com
X-Mailer: QUALCOMM Windows Eudora Light Version 3.0.6 (32)
Date: Tue, 02 Feb 1999 11:44:13 -0500
To: djgpp AT delorie DOT com
From: Paul Derbyshire <pderbysh AT usa DOT net>
Subject: Re: Really strange question about DJ headers.
In-Reply-To: <199902021550.KAA00732@envy.delorie.com>
References: <3 DOT 0 DOT 6 DOT 32 DOT 19990202095727 DOT 008ef860 AT pop DOT netaddress DOT com>
<3 DOT 0 DOT 6 DOT 32 DOT 19990202095727 DOT 008ef860 AT pop DOT netaddress DOT com>
Mime-Version: 1.0
Reply-To: djgpp AT delorie DOT com

At 10:50 AM 2/2/99 -0500, you wrote:
>
>> In a lot of DJGPP headers I see stuff like
>> 
>> __DJ_pid_t
>> #undef __DJ_pid_t
>> #define __DJ_pid_t
>> 
>> where the exact string may vary from __DJ_pid_t. What does this do?
>
>ANSI and POSIX require that all headers be independent - you should be
>able to include stdio.h without stddef.h and expect everything to just
>work.  However, they're not independent - there are some things in
>stddef.h that are required for stdio.h, like size_t.  So, I used the
>above constructs to paste in those kinds of definitions where needed
>(they originate in <sys/djtypes.h>) without causing "multiple
>definitions" errors due to them being in two or more headers.
>
>The first line is replaced with something like "typedef int pid_t".
>The second and third make it so that the next time a header does this,
>*their* first line gets replaced with "".

Ah. So the __DJ_pid_t in this example is already #defined elsewhere. It
looked as though a plain jane identifier had been "declared" and then
#undef'd, which would be very very weird. :-)

Why not just have stdio.h include stddef.h? When working on large projects
with interdependent header files, I just have header files include other
header files as needed. I just observe a hierarchy to make sure I don't
create infinite loops. :-) All the headers in question have include guards
so they'll never get duplicated in a translation unit by accident.
I usually go a step further and have a foo_config.h that gets included
directly or indirectly by any header in the project and that makes sure
some essentials are taken care of, namely:

1. Check predefined macros to make sure the compile environment
   supports the project. For example, if it is C++ and
   __cplusplus is not defined, or if it needs GCC 2.8.0 or greater
   and 2.7.2.1 is in use or a non-GCC compiler is in use, it uses
   #error to output a diagnostic. Better than multiple obscure
   compile errors or worse, run time errors.
2. May set some macros that affect conditional compilation throughout
   the project.
3. May include functions or objects, usually consts, that are going
   to turn up everywhere, e.g.
   extern const int foo_major_version and
   extern const int foo_minor_version
   with a source file including the header and initializing these
   values to something meaningful like 2 and 1.

-- 
   .*.  "Clouds are not spheres, mountains are not cones, coastlines are not
-()  <  circles, and bark is not smooth, nor does lightning travel in a
   `*'  straight line."    -------------------------------------------------
        -- B. Mandelbrot  |http://surf.to/pgd.net
_____________________ ____|________     Paul Derbyshire     pderbysh AT usa DOT net
Programmer & Humanist|ICQ: 10423848|

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019