kearns@read.columbia.edu (Steve Kearns) (07/29/89)
Would someone post an article explaining the proper use of extern when declaring function? When is it neccessary, just a good idea, a bad idea? What about the new 'extern "C" ' I have been hearing about? -steve
ark@alice.UUCP (Andrew Koenig) (07/29/89)
In article <6420@columbia.edu>, kearns@read.columbia.edu (Steve Kearns) writes: > Would someone post an article explaining the proper use of > extern when declaring function? When is it neccessary, > just a good idea, a bad idea? What about the new > 'extern "C" ' I have been hearing about? Saying `extern' by itself in a function declaration has no effect. Thus extern void munge(); means precisely the same thing as void munge(); extern "C" is new in C++ 2.0 . You must use it to declare any C function you wish to call from C++ or any C++ function you wish to call from C: extern "C" double sqrt(double); The declaration informs the C++ compiler that sqrt(double) is a C function so that it can use a C calling sequence for it (which is therefore no longer required to the be the same as the C++ calling sequence). Similarly: extern "C" void frob() { // stuff } says that frob() is a function that will be called from C. -- --Andrew Koenig ark@europa.att.com
dld@F.GP.CS.CMU.EDU (David Detlefs) (07/31/89)
I discovered recently in using G++ that Tiemann has implemented
'extern "C"' so that structure declarations occuring with them do not
become part of the namespace in the same way that they do in C++
linkage. That is, if you write
extern "C" { struct foo { int i; } }
then later in the code "foo" is not recognized as a type name --
instead you must (as in C) use "struct foo". At first I thought this
was a bug, because I had seen no mention of this behavior, but when it
was explained to me that this is a feature, it began to seem like a
great idea. It solves a number of problems, the chief of which is
when a standard C header file declares a structure and a function with
the same name. Cases I've found in our BSD4.3-type system include
"timezone" and "wait".
So, is this part of C++ 2.0? I could not find any reference to this
feature in either Lippman's C++ Primer or Stroustrup's "Type-safe
Linkage" paper. Are there any drawbacks to this that I (and Michael
Tiemann, I guess) don't see? If not, is there any chance it will
become part of the language specification?
--
Dave Detlefs Any correlation between my employer's opinion
Carnegie-Mellon CS and my own is statistical rather than causal,
dld@cs.cmu.edu except in those cases where I have helped to
form my employer's opinion. (Null disclaimer.)bs@alice.UUCP (Bjarne Stroustrup) (08/02/89)
It has been suggested that changing the semantics of structure tags
declared under `extern "C"' would be a good idea. For example,
extern "C" { struct S { ... }; }
would not put `S' in the ordinary name space.
I think this is an ugly and unnecessary `compatibility' hack.
(1) This extension is unnecessary because the resolution of names in 2.0
reduces the incompatibilities to the perverse case:
struct S { ... };
typedef int S; /* legal C, illegal C++ */
S a; /* an int */
struct S b; /* an S */
and to scope effects:
int S;
f() {
struct S { ... };
int i = sizeof(S); /* C and C++ differs! */
}
In particular, 2.0 gets the following examples right:
struct stat { /* ... */ };
extern "C" int stat(const char*, struct stat*);
g() {
struct stat a;
int i = stat("asdf",&a);
}
struct proc { /* ... */ int i; } proc;
h()
{
struct proc a;
proc.i = 1;
a.i = 1;
}
(2) This extension has the probable undesirable effect of making the `struct S'
notation common in C++. The requirement to prefix all structure tags with the
keyword `struct' was an early compatibility hack in C and I have no wish to see
regress to the point where C++ programs are decorated with redundant `struct'
`enum' 'union' and `class' qualifiers. The observation is that almost all C-style
uses of identifiers to name both an object and a type name occur in minimally
transcribed C programs and interfaces to C programs. The suggested extension
would encourage people to use `extern "C"' for all structs that could possibly
be used from C programs. The - often unintentional - undesirable side effect
would be to deny the C++ notational convenience.
(3) When used for functions `extern "C"' has no effect on the type checking of
the program (except for checking that there is not two functions of the same name
with C linkage - since there cannot be). The suggested extension thus is a major
departure that could set a precedense that most likely would lead to of all kinds
of permutations of semantics based on `extern "C"' `extern "Pascal"' etc. to suit
individual implementations and damage portability of programs relying on such
local extensions. In other words, `extern "C"' was designed to govern the relation
between a C++ program and its environment. The proposed extension uses it to
govern the internal operation of a C++ program.
(4) This extension takes up a syntactic construct and could thus prevent future
alternative interpretations. I have no such plans, but one plausible interpretation
of `extern "C"' for structure definitions would be to enforce a particular
`compatible' layout strategy for such structs in a C++ implementation that would
optimize the layout of C++ structs along different lines from a C implementation.
It seems rash to use up this notation except for major gain.
None of these arguments against the extension are compelling but taken together
I see them as sufficient to reject the extension because they show it as not
obviously needed and not obviously harmless.
Note that there are hundreds of little ways in which C++ could be improved.
Unless great restraint is excersized, C++ will crumble under the burden and
complexity of all those `nice' features - and here I'm only talking about
the sensible and useful extensions.