Article View: gnu.g++.help
Article #305Re: Incompatible changes in C++
From: Bjarne Stroustrup
Date: Mon, 19 Nov 1990 17:00
Date: Mon, 19 Nov 1990 17:00
169 lines
7725 bytes
7725 bytes
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.
Technical Details
Message-ID:
<11642@alice.att.com>Path:
arc1-ca.pugleaf.net!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!bsReferences:
<9011190326.AA13113@mole.ai.mit.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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