[comp.lang.c++] Is this legal?

jfw@rome.wpd.sgi.com (john fergus wilkinson) (07/11/90)

Is this legal C++?

class a {
public:
   int x;
};

class b {
public:
   int f() {return a;}
private:
   int a;
};

As I read the discussion in Section 9.9 of Ellis and Stroustrup, this
should be illegal under the
rule "A class-name...may not be redefined in a class declaration after
being used in the
class declaration..."  Am I right?

pcg@cs.aber.ac.uk (Piercarlo Grandi) (07/17/90)

In article <10164@odin.corp.sgi.com> jfw@rome.wpd.sgi.com (john fergus
wilkinson) writes:

   Is this legal C++? [ ... slightly rewritten example follows ... ]

	struct s { ... };
	struct t { int f() { return s; }; int s; };

This should work. The reference to 's' in 'return s' is clearly a
reference to 't::s', not to the 's' class name. There is a rule that
requires member function bodies defined in a class definition to be
considered only after all of the class definition has been seen, and
therefore 't::s' hides 'struct s' within 't'.

Of course you did not follow my fundamental and all important guidelines
to avoid these amboguities, and two of which I will summarize here:

	Never define a memeber fucntion in a class definition, but
	always separately and after the class definition.

	Always prefix 'this->' to any reference to a member in a member
	function body, and similarly for all the other scope indicators.

	Always write first all data members, then all the functions
	member delcarations, even if you are allowed not to.


Exampe, rewritten:

	struct s { int r; };
	struct t { int s; int f(); };
	int t::f() { return this->s; }

This is unambiguous (mostly -- for the sake of brevity I have not put in
storage class idnicators, etc...), most importantly to the human reader.

Let me repeat here my usual tirade about the difference in attitude
between European (algorithmic language) and USA (programming language)
ideas of the role of programs and languages:

	Programs for Europeans are there to communicate the
	implementation of an algorithm,	either to programmatic
	(e.g. compilers, pretty printers, verifiers) or human (even
	more important!) readers. As such it should be as clear and
	unambiguous as possible, and as informative as it can be without
	becoming hard to read because of verbosity.

	The USA position is that programs are there to drive a
	computer to perform a task, and as long as they "work", who
	cares...

   As I read the discussion in Section 9.9 of Ellis and Stroustrup,
   this should be illegal under the rule "A class-name...may not be
   redefined in a class declaration after being used in the class
   declaration..."  Am I right?

I have difficulty understanding what this phrase exactly means, frankly.
Probably it means that you cannot do the following:

	struct s { ... };
	struct t { s u; int s; };

i.e. use it as both as a type name and a field name (reasonable
constraint). Of course this must still be legal and can be used to get
around the constraint:

	struct t { struct s u; int s; };

but then I would regard this as unclear programming practice.
--
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

bs@alice.UUCP (Bjarne Stroustrup) (07/18/90)

In article 8852 Piercarlo Grandi @ Coleg Prifysgol Cymru writes:

 > Let me repeat here my usual tirade about the difference in attitude
 > between European (algorithmic language) and USA (programming language)
 > ideas of the role of programs and languages:
 > 
 > 	Programs for Europeans are there to communicate the
 > 	implementation of an algorithm,	either to programmatic
 > 	(e.g. compilers, pretty printers, verifiers) or human (even
 > 	more important!) readers. As such it should be as clear and
 > 	unambiguous as possible, and as informative as it can be without
 > 	becoming hard to read because of verbosity.
 > 
 > 	The USA position is that programs are there to drive a
 > 	computer to perform a task, and as long as they "work", who
 > 	cares...

This kind of tirade is somewhere between unhelpful and dangerous. It is
a wild generalization that reinforces prejudices and thus allow people
(on BOTH sides of the `divide') to feel superior and avoid learning from
experience. Had the generalization been made about your favorite `minority
group' rather than the unprotected species of `American programmers' and
`European programmers' it would have been recognized as utter bad taste
and an inditement to further antisocial behaviour (and probably been
illegal under the paternalistic laws of the US and UK).

So please, please, cool it. Let's keep the discussions on comp.lang.c++
technical and civil.

Also: Apologies to Piercarlo for using his posting as an excuse to ride
one of my hobbyhorses.

As a European living and working in the US I have had many opportunities
to (suffer from and) pounce on American parochial attitudes about/against
Europeans and other aliens and as a person living in the US and visiting
various parts of Europe often I have had many opportunities (and often no
acceptable alternative than) to defend Americans and other foreigners
against nasty and unfair labeling by parochial Europeans. I assure you
that no side of the Atlantic (or the Pacific) have a monopoly on virtue,
parochialism, competence, or incompetence.

Back to programming languages:

	(I deliberately use `programming language' rather than `algorithmic
	language' here following what I consider common English Academic
	usage - in my case learned at Cambridge (UK). I also feel that
	`algorithmic languages' places an undue emphasis on the computational
	aspect of programs at the expense of structural aspects: We are
	after all considering the general issues in the context of a
	language that supports object-oriented programming. `Algorithmic
	languages' is appropriate for Algol and Fortran, but maybe less so
	for C++ and Smalltalk.)

I clearly think that Piercarlo's characterization of programming languages
is inappropriate. A programming language serves BOTH as a means of communication
between programmers and between programmers and machines. Forgetting one of
the two while concentrating on a specific task is easy, but I don't think
any serious programmer would argue that only one of the two are of importance
in general. Consequently we are talking about emphasis; not about absolutes.

If you forget the human to human communication aspect of programming you
can easily create a maintenance nightmare. Examples abound on both sides
of the Atlantic.

If you forget the human to computer communication aspect of programming
you can easily get a performance nightmare. Examples abound on both sides
of the Atlantic.

(Again:)
	So let us cut the US/Europe characterization:
	It is divisive and inaccurate.

Curiously enough, you can also get a maintenance nightmare from overemphasis
on `structure' and `readability' (especially by emphasis on minutely applied
detailed formalisms) and a performance nightmare from overemphasis on
performance (especially by emphasis on low-level performance at the expense
on overall structure).

There is no simple solution, no holy grail, no silver bullet, so let us cut
the preaching, posturing and labeling, and get on with the hard work of
trying to figure out more reasonable and more manageable ways of designing,
constructing, testing, tuning, documenting, and maintaining systems. It is
so much harder being constructive than simply to criticize.

Further, back to C++ (this is comp.lang.c++ after all): C++ is designed to
be both an effective medium for human to computer communication (that is
primarily the `C part') and an effective medium for human to human
communication (that is primarily the `++ part'). See the `Efficiency and
Structure' sections of the `Notes to the Reader' chapter of my (first) book.
Naturally, like every other language, C++ is not perfect, but at least some
of the tradeoffs in this particular area have proven successful over a wide
range of applications and programming cultures.

	- Bjarne Stroustrup

roger@procase.UUCP (Roger H. Scott) (07/20/90)

In article <PCG.90Jul17114203@odin.cs.aber.ac.uk> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
>...
>	Always prefix 'this->' to any reference to a member in a member
>	function body, and similarly for all the other scope indicators.
The extra clutter of "this->" isn't really necessary.  The same effect
(of disambiguating references to various scopes) can be achieved with lexical
conventions such as naming all data members myFoo and myBar.  There isn't
any risk of conflict with file scope identifiers, because the only file scope
identifiers are class names and they are always spelled ClassName, right? :+}

>
>	Always write first all data members, then all the functions
>	member delcarations, even if you are allowed not to.
If we assume the usual convention that things that appear ahead of other
things (in the order they are read) are more important then I would think
we would want to put the public interface (functions) ahead of the private
information (data), not vice versa.  When I am scanning a class definition
I would rather not see the data *at all* - it is unfortunate that C++
requires that data be declared in the publicly visible class definition.

>
>
>Example, rewritten:
>
>	struct s { int r; };
>	struct t { int s; int f(); };
>	int t::f() { return this->s; }

    struct S { int myR; };
    struct T {int f(); int myS;};
    inline int T::f() {return myS;}

pcg@cs.aber.ac.uk (Piercarlo Grandi) (07/31/90)

"bs" == Bjarne Stroustrup writes:

bs> In article 8852 Piercarlo Grandi @ Coleg Prifysgol Cymru writes:

pcg> Let me repeat here my usual tirade about the difference in attitude
pcg> between European (algorithmic language) and USA (programming language)
pcg> ideas of the role of programs and languages:

pcg> 	Programs for Europeans are there to communicate the
pcg> 	implementation of an algorithm,	either to programmatic
pcg> 	(e.g. compilers, pretty printers, verifiers) or human (even
pcg> 	more important!) readers. As such it should be as clear and
pcg> 	unambiguous as possible, and as informative as it can be without
pcg> 	becoming hard to read because of verbosity.

pcg> 	The USA position is that programs are there to drive a
pcg> 	computer to perform a task, and as long as they "work", who
pcg> 	cares...

bs> This kind of tirade is somewhere between unhelpful and dangerous. It is
bs> a wild generalization that reinforces prejudices and thus allow people
bs> (on BOTH sides of the `divide') to feel superior and avoid learning from
bs> experience. 

Hey! Gross generalizations are of course dangerous, but maybe not
unhelpful. This one, in particular, is at least of historical relevance;
there has been an historical divide and loads of prejudices on both
sides of the Atlantic, and this has been most obvious in the diverse
fortunes of the languages of the algorithmic family, not to mention in
standards committees everywhere.

	As an aside: we still see that in communications, but there the
	positions are reversed: European PTTs pressing for the bag of
	tricks approach, and Americans for the building block one. Too
	bad the bag (actually truckload) of tricks has prevalied there
	as well.

bs> Had the generalization been made about your favorite `minority
bs> group' rather than the unprotected species of `American programmers' and
bs> `European programmers' it would have been recognized as utter bad taste
bs> and an inditement to further antisocial behaviour (and probably been
bs> illegal under the paternalistic laws of the US and UK).

This is a very bizarre statement; I know several people that would not
find not offensive at all being characterized as giving more importance
to "making things work", rather than "communicating algorithms".  Maybe
*you* have a prejudice in this sense :-). I would quote Hilbert (leave
elegance to tailors) or Stallman (on GCC) as people that belong proudly
to the "making things work" camp.

bs> Back to programming languages:

bs> 	(I deliberately use `programming language' rather than `algorithmic
bs> 	language' here following what I consider common English Academic
bs> 	usage - in my case learned at Cambridge (UK).

Maybe. But I understand that people shed blod at Cambridge (and
Manchester, and Amsterdam, and elesewhere) twenty years ago in the
trenches of the great battle to uphold the "algorithmic language"
banner. The battle has been lost, and so the distinction has been
buried, but let's honor its heroes by not forgetting what it was fought
about. :-) :-).

bs>     I also feel that
bs> 	`algorithmic languages' places an undue emphasis on the computational
bs> 	aspect of programs at the expense of structural aspects: We are
bs> 	after all considering the general issues in the context of a
bs> 	language that supports object-oriented programming. `Algorithmic
bs> 	languages' is appropriate for Algol and Fortran, but maybe less so
bs> 	for C++ and Smalltalk.)

Sorry, but we are totally out of synch here: Fortran is emphatically not
an algorithmic language. C++ instead is IMNHO definitely an algorithmic
language. The divide is between languages as notations to express
algorithms, and languages as collections of convenient linguistic forms
and tools.

For example, even if strictly "algorithmic language" should be reserved
historically for members of the Algol family of languages (to which both
Simula 67 and C++ belong by right of birth, even if they are both OO),
it could be applied with clean semantics to Smalltalk, Lisp, ML; while
programming languages are Fortran, Cobol, PL/1, PERL.

Maybe you are swayed by the fact that the ancestor, Algol 60, was
procedural decomposition oriented, which is not however essential to
being an algorithmic language; its immediate successor, Algol 68,
definitely still an "algorithmic language" in any sense of the word (but
for formats, let me sadly add), had all structuring facilities you could
wish (except for scope barriers), not to mention again Simula 67, which
is a strict superset of Algol 60, yet an OO language.

bs> I clearly think that Piercarlo's characterization of programming
bs> languages is inappropriate. A programming language serves BOTH as a
bs> means of communication between programmers and between programmers
bs> and machines.

We are still out synch here. As long as you describe a language as a
means of communication, either with machines or humans, you belong
firmly in the "algorithmic language" camp. The "programming language"
fans believe that what you want is a collection of suitable linguistic
tools or idioms with which to give orders to to accomplish a task, as
opposed to describing an algorithm for communication.

	Incidentally, that is why I am so insistent that a compiler has
	no business rewriting the logic of a program, at least for a
	low level algorithmic language; the description should be
	heeded closely by the compiler. "programming language" people
	instead think that only the effect matters, not the way the
	algorithm is expressed, so are very happy with an optimiser
	that rearranges the logic of their programs, as if they had
	been expressed in an higher level language. This is also why I
	recommend putting explicit storage class and scope indicators
	in C++ programs, even if technically redundant; making the
	description more precise is, to me, important, even if it does
	not affect the translator-wise semantics of the program.

bs> There is no simple solution, no holy grail, no silver bullet, so let
bs> us cut the preaching, posturing and labeling, and get on with the
bs> hard work of trying to figure out more reasonable and more
bs> manageable ways of designing, constructing, testing, tuning,
bs> documenting, and maintaining systems. It is so much harder being
bs> constructive than simply to criticize.

Yup, truly. :-). But to warn that things are not as luminous as they are
purported to be is terribly useful. A false sense of security is the
greatest hazard. :-).

bs> Further, back to C++ (this is comp.lang.c++ after all): C++ is
bs> designed to be both an effective medium for human to computer
bs> communication (that is primarily the `C part') and an effective
bs> medium for human to human communication (that is primarily the `++
bs> part').

So it is an "algorithmic language" after all. Other symptoms: providing
meachanisms to build idioms, instead of providing them directly
(relegating IO and tasking to libraries, for example), which is part of
the C legacy as much as the attention to simplicity (but what about
constructors and destructors then? :-/).

bs> Naturally, like every other language, C++ is not perfect, but at
bs> least some of the tradeoffs in this particular area have proven
bs> successful over a wide range of applications and programming
bs> cultures.

Here we are back to our discussion: C++ (which I like to read as "C +
extensions + classes) as an extension to C is wonderful. It is difficult
to find fault with any of the non OO extensions to C, they are
orthogonal and highly economical, and give real value at little or no
cost (and in areas where Ansi C and C++ overlap and differ, it is
apparent that C++ was done The Right Way).

The OO extensions (the second +), in particular multiple inheritance,
seem (to me at least) somewhat idiomatic and ad hoc, and this is
reflected in the forbidding complexity of the rules pertaining to them,
and in some ugliness of the implementation.

I have this suspicion that they are the "programming language" aspect of
C++. A lot of people are happy with them, because they get many jobs
done in one way or another, but some others (like me) are not so sure
they are as conceptually robust and minimalist as the rest of the
language.

	Note that I do not especially like the technique used by other
	OO language authors to slide difficulties under the carpet by
	abuse of references and dynamic binding or polymorphism, or the
	renounciation by functional language authors of the difficulties
	linked with statefulness, or other irrelevant details :-). C++
	is difficult because easy ways out have been avoided (except for
	virtual multiple inheritance, that is :-/).

Eventually the state of the art will advance, and we all hope that a
full fledged OO language will eventually not need a few hundred pages of
language legalese to be described, or that it will be conclusively
proven wrong our intuition that says that OO is fundamentally simpler
than that. In the meantime the wary will remember that C++ is better
than most, but not quite finished yet. State of the art, but the state
of the art is not that satisfactory.
--
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk