[comp.lang.c++] extern "C"

gas@cs.nott.ac.uk (Alan Shepherd) (10/05/90)

Can someone explain the rational behind the fact that 

	extern "C" foo();

doesn't do what you'd expect (i.e. declare a function foo which has c
linkage and as in pre-ANSI C, any number of arguments) but declares a C
function with no arguments so that a call to foo("hello") for example
results in an unexpected argument error ?  If the ansi option is
specified to C++, this makes more sense, but it behaves exactly the same
without the ansi option.  This makes it impossible to use old-style C
header files without editting them which I thought the introduction of
extern "C" was supposed to facilitate.

Alan Shepherd

jac@gandalf..llnl.gov (James Crotinger) (10/06/90)

  extern "C" does give you C linkage but it does not relieve you
from C++'s strict typing requirements. This is a good thing IMHO. 

  Jim


--
-----------------------------------------------------------------------------
James A. Crotinger   Lawrence Livermore Nat'l Lab // The above views 
jac@gandalf.llnl.gov P.O. Box 808;  L-630     \\ // are mine and are not 
(415) 422-0259       Livermore CA  94550       \\/ necessarily those of LLNL.

jimad@microsoft.UUCP (Jim ADCOCK) (10/09/90)

In article <1990Oct5.090712.7318@cs.nott.ac.uk> gas@cs.nott.ac.uk (Alan Shepherd) writes:
|Can someone explain the rational behind the fact that 
|
|	extern "C" foo();
|
|doesn't do what you'd expect (i.e. declare a function foo which has c
|linkage and as in pre-ANSI C, any number of arguments) but declares a C
|function with no arguments so that a call to foo("hello") for example
|results in an unexpected argument error ?  If the ansi option is
|specified to C++, this makes more sense, but it behaves exactly the same
|without the ansi option.  This makes it impossible to use old-style C
|header files without editting them which I thought the introduction of
|extern "C" was supposed to facilitate.

I'd expect the extern "C" directive to provide a mapping between the 
implementation of one C++ compiler and one C compiler.  Thus, the 
interpretation placed on declarations within a extern "C" directive 
depends on both the C++ implementation and the C implementation.  One
obvious problem is that a given C++ implementation probably only implements
one extern "C" directive -- but is the resulting "C" compiler being 
targeted a K&R C compiler, or an ANSI-C compiler?  Depending on your
K&R C compiler, and/or your ANSI-C compiler, the way pass parameters are
handled may be very different.  Like C++, an ANSI-C compiler may depend
on function prototypes to allow "Pascal"-style calling conventions be used,
which would not be applicable to K&R style compilers.  Bottom line to me
is: what goes on in an extern "C" directive is implementation dependent --
dependent on both a particular C++ compiler implementation and a particular
C compiler implementation [not to mention the linker the two implicitly have
in common]  Maybe if C++ compilers implemented both a "ANSI-C" and a 
"CLASSIC-C" directive things would make more sense.

gas@cs.nott.ac.uk (Alan Shepherd) (10/10/90)

I've had several responses to my original question about extern "C".
As a summary, I wanted to know why it was necessary to prototype
functions within the scope of an extern "C" declaration rather than
treat 'extern "c" foo()' as an old-style C compiler would.  Most
people have basically said that it's necessary for prototyping.
Someone pointed out that 'extern "C" foo(...)' would do what I wanted,
but this syntax failed for declaring a pointer to a function - I had
to cast everything explicitly (is there any way in C++ to declare a
pointer to a general fn, rhater than specific types ?)

However, all the solutions seem to rule out the possibility of using C
header files within C++.  This (at least for the time being when a lot
of extremely useful software e.g. isode package is written in C) is
crazy.  G++ actually does the sensible (in my view anyway :-)) thing
and I would use that in preference to AT&T anyday were it not for
other software constraints.

Alan Shepherd

ggs@ulysses.att.com (Griff Smith) (10/11/90)

In article <1990Oct10.062518.23722@cs.nott.ac.uk>, gas@cs.nott.ac.uk (Alan Shepherd) writes:
> 
> I've had several responses to my original question about extern "C"...
> ... However, all the solutions seem to rule out the possibility of using C
> header files within C++.
> 
> Alan Shepherd

I'm not sure what you're basing this on, since AT&T C++ 2.0 uses
standard C header files inside C++ wrappers that discard the useless C
function definitions.  If you have seen this solution and object to the
aesthetics, so be it.  Given that the wrapper would be necessary anyway
to supply declarations with full type checking, I find it hard to
quibble about the details.
-- 
Griff Smith	AT&T (Bell Laboratories), Murray Hill
Phone:		1-201-582-7736
UUCP:		{most AT&T sites}!ulysses!ggs
Internet:	ggs@ulysses.att.com

gas@uk.ac.nott.cs (Alan Shepherd) (10/15/90)

In article <13870@ulysses.att.com>, ggs@ulysses.att.com (Griff Smith) writes:
|> In article <1990Oct10.062518.23722@cs.nott.ac.uk>, gas@cs.nott.ac.uk (Alan Shepherd) writes:
|> > 
|> > I've had several responses to my original question about extern "C"...
|> > ... However, all the solutions seem to rule out the possibility of using C
|> > header files within C++.
|> > 
|> > Alan Shepherd
|> 
|> I'm not sure what you're basing this on, since AT&T C++ 2.0 uses
|> standard C header files inside C++ wrappers that discard the useless C
|> function definitions.  If you have seen this solution and object to the
|> aesthetics, so be it.  Given that the wrapper would be necessary anyway
|> to supply declarations with full type checking, I find it hard to
|> quibble about the details.
|> -- 
|> Griff Smith	AT&T (Bell Laboratories), Murray Hill

My point is that you have to edit the C header files either manually
or automatically.  In some cases, automatic editing is not trivial.
For example, we use the isode OSI development package extensively
which is written in old style C and hence the header files require a
lot of editing to even be incorporated using extern "C".  Since the
software producer does not support C++, this has to be done each time
a new version is released.

Understandably, I would rather not have to do this.  Since g++ does
not implement extern "C" in the same way and thus it allows inclusion
of old-style C headers, I would much rather use it than AT&T's version
if it were possible.  Unfortunately, we also use some commercial
software which rules this choice out.  G++ has several other
advantages, not least of which is that it is a compiler rather than a
translator which greatly facilitates debugging.  For the more
pecuniary minded, it is also free !

Alan Shepherd