Xref: utzoo gnu.g++.help:152 comp.lang.c++:10451 Path: utzoo!utgpu!watserv1!watmath!uunet!shelby!apple!julius.cs.uiuc.edu!usc!elroy.jpl.nasa.gov!swrinde!ucsd!pacbell.com!att!att!dptg!ulysses!andante!alice!bs From: bs@alice.att.com (Bjarne Stroustrup) Newsgroups: gnu.g++.help,comp.lang.c++ Subject: Re: Incompatible changes in C++ Summary: further clarification Message-ID: <11642@alice.att.com> Date: 19 Nov 90 17:00:49 GMT References: <9011190326.AA13113@mole.ai.mit.edu> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 170 rms@AI.MIT.EDU (Richard Stallman @ Gatewayed from the GNU Project mailing list help-g++@prep.ai.mit.edu) writes in response to a note by me: > I am not aware of a having ``change(d) the behavior of struct and union, > breaking almost all C programs.'' In fact, nothing C++ does to structs > or unions break any C programs. I suspect rms is misinformed. > > My understanding is that the following declaration > > struct foo { int a, b; }; > > is handled by C++ in a way incompatible with C. C++ defines `foo' as > a typedef, but C does not. > > Is this not so? I would be glad if it is not. But if it is, the > incompatibility breaks many C programs because they use the same > symbol both as a structure tag and as a variable (often a variable > whose type is or points to that structure). You can be happy. What you described is not the whole story. C++ does indeed allow you to use the name of a user-defined type (structure tag) without a prefix. However, for C compatibility names can be declared to refer to both a type and an object and the compiler can resolve this overloading. For example: struct s { int m; } s; in both C and C++ declares a struct and an object both named `s' and in both languages you can use the prefix `struct' to disambiguate: s a; /* error `s' is an object of struct `s' */ struct s b; /* ok */ s.m = 7; /* ok */ Similarly, the `struct stat' `stat()' ambiguity is handled compatible. I consider this very ugly, it does complicate compilers, and most experienced C++ users would have prefered this ugly compatibility hack not to be required of their compilers. My original C++ compiler, cfront, always supported this. There is one rare case where C++ is not C compatible. If the name of a function or an object is hidden by a local struct name the global name must be explicitly qualified to be accessible. Default, the local name is used: int s; void f() { struct s { int m; }; struct s a; /* ok */ s++; /* ok in C, error in C++ */ ::s++; } I consider this a small price to pay for being able to use type names without prefixes. > The grammar ambiguity shows up in > > int (x); > > which could either declare `x' as an integer or convert it to one. Not in C++. Again, C++ is defined to follow C in such cases. `int (x);' declares `x' to be an `int.' A quick look in Ellis & Stroustrup: ``The Annotated C++ Reference Manual'' (Addison Wesley 1990) would have told you that. The reference manual proper from that book is the base document for the ANSI standardization of C++. > I think that my design choices in this area traded > implementor convenience for user convenience. > > I don't see that they help the implementors enough to compensate for > the inconvenience to the users. I think you misread. The design giver users convenience and the implementors more work; not the other way around. Ideally things should be designed for the convenience of both users and implementors, but where a choice must be made I favor users. > Users switching from C to C++ wish that C++ were a superset of C. > There is no fundamental or important reason it is not. The real > features of C++ are upward compatible with C. The problems are all > superficial. SOME users switching from C to C++ wish that C++ were a superset of C. MOST users with even a minor amount of C++ experience realize that the inconveniences caused by the few remaining incompatibilities are minor and that full ANSI C compatibility would not only invalidate the large existing body of C++ code but would seriously damage C++'s type system. For example, C++ requires function prototypes rather than having them optional like ANSI C. Please realize that for many C++ users even the current degree of C compatibility is a burden on everyday use and learning (not all C++ programmers used to be C programmers). I consider the number of C++/C incompatibilities quite amazing small giving the difference in aims of the two languages and the number of concepts supported by C++ that have no counterpart in C. I think that C++'s stated goal of `no gratuitous incompatibilities' or `as close to C as possible - but no closer' has been met to a larger degree than anyone would have had the right to expect. It is a fact though, that some compiler writers have taken liberties with the language definition and in particular have been uninterested in the details of C compatibility. These problems are not very common any more and with the ANSI C++ committee working there is less excuse for divergent implementations. I'd like to encourage users to encourage their compiler suppliers to implement the language as currently defined (including these C compatibility hacks). These days users do have a choice of C++ suppliers and need not be satisfied with half-measures. > These problems are insoluble today, but would have been so easy to > avoid at the start. For example: make `class' do a typedef > automatically but not `struct' or `union'. Don't use the syntax TYPE > (EXP)--use something like (TYPE) [ EXP ] instead. Yes, it would indeed have been nice if I had possesed 20/20 foresight, but I didn't and the problem is not completely trivial. Consider: complex z2 = z1+complex(PI,2.8); // C++ complex z2 = z1+(complex)[PI,2.8]; // suggestion I suspect I would have had a hard time convincing users to adopt the latter syntax. C's syntax is already so contorted that additions are harder to make than one would like. There have been many suggestions of how to make C++ an exact superset of C by segregating the ++ features from the C features by syntactic means. I consider such notions short sighted. There are too many languages that do not posses a single syntax or a single type system and are thus simply a collection of semi-random features without even the semblance of unity. C++ does not belong to that class of languages. Its differences from C are not arbitrary but follows directly from that view. > An incompatibility that could have been avoided at such small cost > must be considered gratuitous. It seems that Stroustrup decided > arbitrarily to reject upward compatibility as a goal, and thus > accepted incompatibilities in the absence of any need. I beg to differ. I also think you ought to read the ARM or at least consult with a C++ expert before you start making statements with phrases such as `must be considered gratuitous,' `in the absence of any need,' and `spirit of careless incompatibility' in the discussion of my work. As someone who has made himself into a public figure you have the obligation to refrain from random flaming. I don't see you could possible have the prerogative of telling me what my aims ought to be, and especially not what they ought to have been 10 years ago. If you nevertheless do, please at least try to get your facts straight. Note also that many C++ programmers resent being told by non-C++ programmers what their language ought to be. I understand that sentiment well.