Mail Archives: djgpp-workers/2001/01/07/16:40:15
In an earlier message
<http://www.delorie.com/djgpp/mail-archives/browse.cgi?p=djgpp-workers/2000/12/14/19:13:06>
I explained how the standard C header files are supposed to work in
C++ with respect to namespace std. In the present message I will
outline a method for getting this working in DJGPP. In a separate
message (to follow) I will show some examples of how things fail to
work at present.
The header files that require patching are the 15 header files of
the original ANSI C standard, plus the 3 introduced by the 1995
amendment, except that those which contain only macros can be left
alone. (The 6 header files introduced by the C99 standard do not
exist in C++, and so are not a problem.)
There needs to be a way for the <*.h> headers to know whether they
were included directly or via a <c*> header. It's not possible to
rely on the <c*> include guard macros for this, because that would
cause incorrect results if a <*.h> header is directly included after
having already been included via the corresponding <c*> header.
Instead it is necessary to replace each <c*> header with something
like this (taking <cstdio> as an example):
#define __dj_no_hoist_
#include <stdio.h>
#undef __dj_no_hoist_
Note that the same temporary macro can (and almost certainly should) be
used for each <c*> header. (Question: What naming convention is used for
DJGPP macros? Is __dj_no_hoist_ acceptable? Or __dj_via_cplusplus_header_?
In the examples below I will continue to use __dj_no_hoist_.)
Here is the layout I propose for a typical <*.h> file:
#ifndef __dj_include_foo_h_
#define __dj_include_foo_h_
#ifdef __cplusplus
namespace std {
extern "C" {
#endif
// main foo.h contents go here
#ifdef __cplusplus
}
}
#endif
#endif /* !__dj_include_foo_h_ */
#if !defined(__dj_no_hoist_) && !defined(__dj_ENFORCE_ANSI_FREESTANDING)
// hoist all standard foo.h symbols here
#ifndef __STRICT_ANSI__
// hoist all non-standard foo.h symbols here
#endif /* !__STRICT_ANSI__ */
#endif /* !_dj_no_hoist_ && !__dj_ENFORCE_ANSI_FREESTANDING */
I'm assuming that non-standard symbols get the same treatment as
standard symbols with respect to namespace std, as this seems least
likely to cause confusion.
Note that all hoisting is done outside of the include guards, because
otherwise it would not occur at all if the <*.h> header happened to
be included after the corresponding <c*> had already been included.
Hoisting the same thing multiple times is legal, so there is no
problem here.
Any comments?
Stephen
PS. One of the 18 headers common to C and C++ is missing altogether
from DJGPP 2.03. Here's all that is needed for <iso646.h>:
#ifndef __cplusplus
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=
#endif
<iso646.h> is macros-only (and, in fact, completely vacuous in C++),
so it is unaffected by the above discussion of namespace std.
- Raw text -