Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!apple!sun-barr!rutgers!dptg!ulysses!andante!alice!bs From: bs@alice.UUCP (Bjarne Stroustrup) Newsgroups: comp.lang.c++ Subject: Re: extern - when to use it Summary: what not to do with extern "C" Message-ID: <9727@alice.UUCP> Date: 2 Aug 89 16:22:47 GMT References: <6420@columbia.edu> <9702@alice.UUCP> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 84 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.