From: jss@lucid.com (Jerry Schwarz)
Subject: Re: Standard library functions and macros
Reply-To: jss@lucid.com (Jerry Schwarz)
Organization: Lucid, Inc.
Date: Tue, 5 Jan 93 03:25:55 GMT

In article <1993Jan04.231519.8704@microsoft.com>, jimad@microsoft.com (Jim Adcock) writes:
|> In article <1993Jan2.191336.28542@taumet.com> steve@taumet.com (Steve Clamage) writes:
|> |If an implementation uses the same library for C and C++, which is
|> |true for current implemenations, you can successfully do this:
|> |	extern "C" int puts(const char *);
|> |	int main() { puts("Hello world\n"); return 0; }
|> |You are just not assured the code will work.
|> 
|> How about implementations and programmers that want to continue to
|> share code between C and C++ implementations?  Let's say a program
|> that it created from some "C" files and some "C++" files, and each of
|> these files in turn calls some of the standard-C functions.  How are
|> you going to make this work?  Seems to me you are requiring 
|> "C++ calling convention" of the standard-C functions called by the
|> C++ files, whereas the standard-C functions called from the "C" files
|> would have to follow "C" calling convention.  At the very least this
|> seems to me to be saying that you're requiring dual-entry stubs of
|> all the library functions.  And then how do these things coexist in
|> one library and get linked in correctly?  Can you point to even one
|> existing implementation that implements your proposed changes, and
|> which continues to allow mixed Cfile/C++file programs to be compiled and linked?

I really don't understand Jim's concerns. All the vendors (of
Unix compilers) I've looked at take a similar approach to this problem.
As far as I can tell we would have no problem accomodating the currently
proposed X3J16 requirements.

I'll describe our approach in more detail. (I usually avoid
specific discussion of Lucid's compiler in this group, but
it seems appropriate here.)

Lucid supplies a large collection of header files with its
compiler that allow use of the vendor (Sun) supplied C libraries. 
We share these headers between C++ and C without much problem.  
These headers check for #ifdef __cplusplus and "do the right thing".
When compiling C++ they insert extern "C" as appropriate.
In C++ modes we have also found it useful to define variants
of some of the C functions using the static inline technique
discussed previously by Steve.

For example, in C++ modes our headers contain (after expansion of
some macros that allow us to control variation between compilation modes)

    typedef void (*__sigtype)(int);
    typedef void (*__alt_sigtype)(int,int,struct sigcontext*,char*);

    /* The C standard declaration */
    extern "C" __sigtype signal(int,__sigtype) ;

    /* A variant expected by Sun programmers */
    extern "C++" inline __alt_sigtype signal(int __sig,  __alt_sigtype __h) {
        return (__alt_sigtype)signal( __sig, (__sigtype)__h) ;
    }

The extern "C" variant gets linked directly to Sun's C library
without any problems. We don't need stubs.

The variant was required because that is, in fact, the type of signal
according to the Sun man pages

When compiling in strict ANSI C mode, the header just expands to

    typedef void (*__sigtype)(int);
    __sigtype signal(int,__sigtype);

    -- Jerry Schwarz
Newsgroups: comp.lang.c++