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.