Topic: About virtual keyword


Author: "J Scott Peter XXXIII i/iii" <speter@dreamworks.dot.com>
Date: 1998/03/13
Raw View
Kirk Odle wrote in message <3505e10d.0@news.ghgcorp.com>...
>Steve Clamage wrote in message <6d4951$s83@engnews1.Eng.Sun.COM>...
>
>>In many program development situations, changing source code is a
>>difficult and expensive process. Every change, no matter how seemingly
>>trivial, requires elaborate approval, testing, and validation. (Examples
>>are military and saftety-critical application areas. You really don't
>>want casual changes to the programs that control nuclear missiles
>>or hospital life-support sytems.) Adding a new language keyword means
>>potential changes to source code that are unrelated to improving
>>the product.
>
>I am frequently disappointed by the apparent disregard for
>process-enhanced development that many proponents of new language
>features often display. The purpose of language standardization is the
>achievement of language stability in all its forms.  Changes to the
>language that affect existing code such that it changes behavior should
>be avoided as they will ultimately detract from the language itself by
>devaluing the code already invested by its users.
>
>I like the rule-of-thumb suggested by Stroustrup; the cost of adding a
>new language feature should be one kidney.

So how many members of the Draft committee are now left with only one (or
zero) kidneys?

Seriously, the Draft standard, along with other recent changes to C++ have
added many, many features, and several keywords to boot.  I, for one, am
hard pressed to see the value of some of these, and if the price of a
keyword is deemed so high, then certainly many fail the test. (E.g.
"typename" [who needs it?], "mutable" [could have been "~const"], and
ferchrisakes "and", "or", "not", and their dozen brethren.)

Gentlemen, I find your arguments spurious.  A suggestion for a new
feature/keyword should be argued on its merits, not with a warning on how
astronauts are going to crash because of a new keyword.  If that were the
case, then many of the above keywords should certainly have been rejected.

In that spirit: "override" is an obviously useful and long-overdue
addition that serves the dual function of documenting semantics, and
catching a sometimes hard-to-find bug, one that I and probably most
readers of this group have been subject to more than once.

>What's wrong here? The magic keyword was supposed to protect me. I guess
>I still have to look at the base class before I derive a new class from
it.
>The horror, the horror.

The argument that "override" will not catch *all* errors of this type is
also spurious, an example of the "if it's not a panacea, it's undesirable"
fallacy. And I find the attitude behind Mr. Odle's sarcasm to be similar
to "real men don't need language-level protection from errors" attitude.
Such an attitude was also used to oppose such basic error-catching
mechanisms as "const" and function prototypes. ("What's wrong here? The
function prototype was supposed to tell me exactly what the function does.
I guess I still have to look at the actual function definition before
calling it".)

A more appropriate application of sarcasm would be to keyword-paranoia: Oh
no! I have to grep for all usages of "override" in my source and change
them!  Or at least set a command-line switch to disable new keywords!
That could take months!
Seriously, new keywords are the least of the worries of porting your code
to a new standard, when the need comes about.  Things such as the changing
of the scope of "for" variables, the constant evolution of overload
resolution, and the removal of ".h" from header files, cause far more
pain.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/03/11
Raw View
Steve Clamage wrote in message <6d4951$s83@engnews1.Eng.Sun.COM>...

>In many program development situations, changing source code is a
>difficult and expensive process. Every change, no matter how seemingly
>trivial, requires elaborate approval, testing, and validation. (Examples
>are military and saftety-critical application areas. You really don't
>want casual changes to the programs that control nuclear missiles
>or hospital life-support sytems.) Adding a new language keyword means
>potential changes to source code that are unrelated to improving
>the product.

That is the case where I work.  Our tools area is rated SEI CMM level 4
and is the largest C++ production center in its division.  A
labor-month of C++ development in that area yields an average of 200
SLOC. About 15% is actual coding. The rest is analysis, design,
inspection, testing, verification and certification.  These tools touch
the bits in load images for man-rated flight control systems, so the
product failure rates must be tightly controlled.

I am frequently disappointed by the apparent disregard for
process-enhanced development that many proponents of new language
features often display. The purpose of language standardization is the
achievement of language stability in all its forms.  Changes to the
language that affect existing code such that it changes behavior should
be avoided as they will ultimately detract from the language itself by
devaluing the code already invested by its users.

I like the rule-of-thumb suggested by Stroustrup; the cost of adding a
new language feature should be one kidney.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/03/03
Raw View

Ross Bleakney wrote in message <6dfj0m$2g1$1@wrqnews.wrq.com>...
>I think the use of the "override" keyword is an excellent suggestion.  The
>override keyword should apply to all functions which have the same name as
a
>virtual base function.  This would prevent the highly annoying and time
>consuming problem of writing a function that did not quite override the
base
>function (this happens if you misspell the function).


No. It prevents some but not all cases of the problem.  Notice:

  class Example {
    public:
    virtual int A(int);
    virtual int A(int, int);
    };

  class Derived: public Example {
    public:
    override int A(int); // oops! I really meant to override (int,int)!
    };

What's wrong here? The magic keyword was supposed to protect me. I guess
I still have to look at the base class before I derive a new class from it.
The horror, the horror.




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Loic Tregan <Loic.Tregan@cert.fr>
Date: 1998/03/04
Raw View
Ross Bleakney wrote:
>
> I think the use of the "override" keyword is an excellent suggestion.

As long as my opinion may be interesting to other peapole, I support
this new keyword too.
It has been successfully used by Delphi for 4 years.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1998/03/01
Raw View
In article <19980226203101.PAA29137@ladder02.news.aol.com>,
ziporama@aol.com says...
> JHB NIJHOF writes:
>
> >There is a need to repeat it: a function `T f() const'
> >returns a `T const', which differs from the object returned
> >by `T f()': you can overload on different const-ness, for instance.
> >So declaring a function 'T f() const' and defining it
> >as 'T f()' is about the same as declaring a function 'int f()'
> >and defining it as 'char* f()'.
>
> My (limited) unstanding tells me that 'T f() const' does NOT return type 'T
> const' (else i should think you would declare it 'T const f()'). Rather, 'T f()
> const' declares a function 'f()' which promises not to change the invoking
> object and returns 'T'.
> PLEASE correct me if i misunderstand this point.

Your understanding of this point looks correct to me.  In CD2, this is
in section 9.3.2 [class.this], paragraph 2.  I _seriously_ doubt that
there have been anything more than minuscule changes between CD2 and
the FDIS in this area.  (In fact, I'd be a little surprised if there
were any changes in this area at all.)

--
    Later,
    Jerry.

The Universe is a figment of its own imagination.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ross Bleakney" <RossB@wrq.com>
Date: 1998/03/03
Raw View
I think the use of the "override" keyword is an excellent suggestion.  The
override keyword should apply to all functions which have the same name as a
virtual base function.  This would prevent the highly annoying and time
consuming problem of writing a function that did not quite override the base
function (this happens if you misspell the function).





[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/02/25
Raw View
James Kuyper wrote:
>
> Christopher Eltschka wrote:
> ...
> > Well, the return type is not redundand, given that (a) the declaration
> > and the definition need not be in the same file and (b) the return type
> > does matter in the definition as well as where used (and usually only
> > the declaration is available).
>
> You should always #include the header file declaring a function
> prototype, in the file where the function is defined; otherwise, how can
> you be sure that prototype and definition match? The claim that the
> return type of a function is redundant in the definition, was base upon
> the assumption that the function prototype was in scope.
>

While what you tell here is a good programming rule, it's not a
requirement. That is, code is legal C++ even if you don't do it
(if it is good C++ is another question).
Also note that - unlike C - C++ gives you not much compiler help
in checking if the declaration and definition match. Effectively
the only thing you are really be able to check is the return value.
If the argument lists differ, the compiler just compiles to different
functions (however, things like int/int& may be catched). In this
case, even a non-matching return type will not be caught...

> >
> > Example:
> >
> > // file general.h:
> >
> > class A {};
> > class B { B(A); }
> > class C { C(B); }
>
> To apply to this argument, general.h should include:
>
>         B f();
>

Not mandated by the C++ standard, therefore not suitable for
depend on it in language features. If something is redundant
when following some coding standard, it doesn't mean it's always
redundant (and could therefore be omitted).
There's a difference between legal C++ and good C++. If something
is redundant must only be determined by the set of legal C++
programs (which is a superset of the good C++ programs).

> >
> > ----------------------
> > // file with definition:
> >
> > #include "general.h"
> >
>
> With the prototype in scope, the 'B' in the following definition is
> redundant, because their is no return type other than 'B' which could
> legally be put there.
>

True, but again remember that nothing in the standard requires
the prototype being present. Therefore my example is valid (because
it's valid C++ according to the standard). And therefore, in general
the return type is *not* redundant.

> > B f()
> > {
> >   A a;
> >   return a; // B::B(A) must be called; would not be known
> >             // without knowing return type
> > }


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: abell8920@mindspring.com (Andrew Bell)
Date: 1998/02/26
Raw View
On 10 Feb 98 07:21:02 GMT, Phlip <tegan@deltanet.com> wrote:
>Because keywords are a precious resource and difficult to add to a language
>(unless you are Perl, where all variables are marked by $)

In D&E, Stroustrup talks about how he added a new keyword to C++ at
one point (while it was still AT&T only); no one noticed for two
months.  Keyword clashes are less common that one typically would
expect, and are straightforward to fix.  Other than the rare variable
name that would need to be changed, what would make a new keyword
difficult to add?

Overuse of keywords is a *much* bigger problem.  Consider const, for
example.  It means both globally const, and const in a specific scope,
and as such causes confusion -- at least among us mere mortal
programmers.

Likewise, "virtual" as a keyword could mean that the function is the
base class function through which derived class versions will be
called, or it could mean that the function is an overloaded version of
this class's base class.

Static?  In one case, it means a variable or function has file scope;
in other places it means quite different things.

Overuse of the same keyword for significantly different keywords is,
in my experience, far worse than having more keywords.

Andrew Bell
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/02/26
Raw View
In article 12057988@news.mindspring.com, abell8920@mindspring.com (Andrew Bell) writes:
>On 10 Feb 98 07:21:02 GMT, Phlip <tegan@deltanet.com> wrote:
>>Because keywords are a precious resource and difficult to add to a language
>>(unless you are Perl, where all variables are marked by $)
>
>In D&E, Stroustrup talks about how he added a new keyword to C++ at
>one point (while it was still AT&T only); no one noticed for two
>months.  Keyword clashes are less common that one typically would
>expect, and are straightforward to fix.  Other than the rare variable
>name that would need to be changed, what would make a new keyword
>difficult to add?

A famous example: Standard Unix header files had public C interfaces
that used "class" as an identifier. It simply was not possible to
compile C++ programs that needed those headers.

Changing standard system header files generally breaks existing programs
and libraries. Such problems are not impossible to solve, but they can
be very difficult. Consider that programs and libraries come from many
different sources who do not update their products in lock-step.

In many program development situations, changing source code is a
difficult and expensive process. Every change, no matter how seemingly
trivial, requires elaborate approval, testing, and validation. (Examples
are military and saftety-critical application areas. You really don't
want casual changes to the programs that control nuclear missiles
or hospital life-support sytems.) Adding a new language keyword means
potential changes to source code that are unrelated to improving
the product.

---
Steve Clamage, stephen.clamage@sun.com




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ziporama@aol.com (Ziporama)
Date: 1998/02/26
Raw View
JHB NIJHOF writes:

>There is a need to repeat it: a function `T f() const'
>returns a `T const', which differs from the object returned
>by `T f()': you can overload on different const-ness, for instance.
>So declaring a function 'T f() const' and defining it
>as 'T f()' is about the same as declaring a function 'int f()'
>and defining it as 'char* f()'.

My (limited) unstanding tells me that 'T f() const' does NOT return type 'T
const' (else i should think you would declare it 'T const f()'). Rather, 'T f()
const' declares a function 'f()' which promises not to change the invoking
object and returns 'T'.
PLEASE correct me if i misunderstand this point.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/02/27
Raw View
Andrew Bell wrote:
>
> On 10 Feb 98 07:21:02 GMT, Phlip <tegan@deltanet.com> wrote:
> >Because keywords are a precious resource and difficult to add to a language
> >(unless you are Perl, where all variables are marked by $)

> Overuse of keywords is a *much* bigger problem.  Consider const, for
> example.  It means both globally const, and const in a specific scope,
> and as such causes confusion -- at least among us mere mortal
> programmers.

const, unlike static is _not_ overloaded.

Wether virtual is overload depends on the defintion on overloaded,
but I would say that it isn't.

But when someone reads virtual it can mean overrides or new
virtual function. It could help the code maintainner as well as
the original author to add the keyword override.

Not marking a function as 'override' would be allowed for
compatibillity but deprecated. Compilers would emit a
warning.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1998/02/19
Raw View
Oleg Zabluda wrote:
>
> Valentin Bonnard <bonnardv@pratique.fr> wrote:
> : I already write code like this:
>
> : #define OVERRIDE
>
> : struct der : base {
> :     OVERRIDE void foo ();
> : };
>
> : then if override can go into C++ X0, I'll change the define to:
>
> : #define OVERRIDE override
>
> You can always write
>
> struct der : base {
>    /*override*/ void foo ();
> };
>
> To cleanly achieve the same goal.

Which goal? your version is significantly harder to convert, should
'override' be added in C++ X0. Making the conversion easy appears to be
Valentin's primary goal.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David Abrahams <abrahams@motu.com>
Date: 1998/02/19
Raw View
The use of macros at all is not so clean, as I'm sure you know. Might I suggest:

class DirectBase : public IndirectBase {...};

class Derived : public DirectBase
{
private:
    // DirectBase virtual function implementations
    void fun1();
    void fun2();

   // IndirectBase virtual function implementations
   void fun3();
   void fun4();
};

etc...

Comments work just as well as an empty macro, are safer, and are capable of
carrying more useful information. In my experience, using an empty macro that
is intended to be changed to a keyword "when the language feature is enabled"
often causes real problems. It gives readers the illusion that the macro is
actually doing something, and often causes compile errors when the language
feature actually goes into effect.

-Dave

-----

Oleg Zabluda wrote:
>
> Valentin Bonnard <bonnardv@pratique.fr> wrote:
> : I already write code like this:
>
> : #define OVERRIDE
>
> : struct der : base {
> :     OVERRIDE void foo ();
> : };
>
> : then if override can go into C++ X0, I'll change the define to:
>
> : #define OVERRIDE override
>
> You can always write
>
> struct der : base {
>    /*override*/ void foo ();
> };
>
> To cleanly achieve the same goal.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/02/20
Raw View
James Kuyper <kuyper@wizard.net> wrote:
: Oleg Zabluda wrote:
: >
: > Valentin Bonnard <bonnardv@pratique.fr> wrote:
: > : I already write code like this:
: >
: > : #define OVERRIDE
: >
: > : struct der : base {
: > :     OVERRIDE void foo ();
: > : };
: >
: > : then if override can go into C++ X0, I'll change the define to:
: >
: > : #define OVERRIDE override
: >
: > You can always write
: >
: > struct der : base {
: >    /*override*/ void foo ();
: > };
: >
: > To cleanly achieve the same goal.

: Which goal? your version is significantly harder to convert, should
: 'override' be added in C++ X0. Making the conversion easy appears to be
: Valentin's primary goal.

I think it is significantly easier to convert. Use the 'replace'
feature of your favorite text editor to do the conversion. Unix
droids might evan do it from a command line in about a gazillion
different ways.

The ease comes from the fact that you are guaranteed not to have any
undesireable side effects from a macro. Plus you get far less
ugly code afterward. Picture this:

#define VIRTUAL virtual

class A { VIRTUAL void f(); }

Blech...

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Philippe Nobili <pnobili@imaginet.fr>
Date: 1998/02/20
Raw View
Oleg Zabluda wrote:
>
> Valentin Bonnard <bonnardv@pratique.fr> wrote:
> : I already write code like this:
>
> : #define OVERRIDE
>
> : struct der : base {
> :     OVERRIDE void foo ();
> : };
>
> : then if override can go into C++ X0, I'll change the define to:
>
> : #define OVERRIDE override
>
> You can always write
>
> struct der : base {
>    /*override*/ void foo ();
> };
>
> To cleanly achieve the same goal.
>

It achieves the same goal if the macro is to be used only in one place.
If it is used all over the source code, you will have to search every
possible file for '/*override*/' .... whereas the macro's definition may
be placed in an included header file.

            regards,
                      Phil.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/02/20
Raw View
Chris Uppal wrote:

[...]

> > Could you show me an implementation of a virtual member function which
> > you won't understand if you don't know that it is virtual?
>
> class base
> {
>    public:
>       virtual bool precheckAction();
>       void Action();
>   private:
>       virtual void doAction();
> };
>
> void
> base::Action()
> {
>    if (!checkAction())
>       throw ...;
>    doAction();
> }
>
> /* virtual */ bool
> base::precheckAction()
> {
>    return true; // why not "false" ?
> }

I'd argue that even if you know it's virtual, you don't understand
the reason why it's true and not false (you are helped guessing,
of course). What about a comment?

>
> /* virtual */ void
> base::doAction()
> {
>     // what the f*** is this for ?
> }

Deserves a comment, too. For me it looks like a forgotten
implementation... (if it does nothing, why was it not declared
pure virtual, without a body at all?)

>
> I contend that the bodies of base::precheckAction() and base::doAction() are
> not comprehensible without knowing that they are virtual and designed to be
> overridden.

I contend that the bodies are not comprehensible without knowing
their exact role in the class (which includes, of course, knowing
it to be virtual). However, this role can only be found out by
either helpful comments, or reading the rest of the class yourself.
In both cases you will find out that they have to be virtual anyway
(in the first case from explanation, in the second case from class
definition). Therefore you don't get additional information through
repeating the virtual keyword.
OTOH, if you are overriding the function in derived classes, it's
automatically virtual. So you would have to repeat "virtual" here,
too. However, the implementation would probably not depend on it
being virtual, so the virtual keyword would not help here.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/02/20
Raw View
Philippe Nobili <pnobili@imaginet.fr> wrote:
: Oleg Zabluda wrote:
: >
: > Valentin Bonnard <bonnardv@pratique.fr> wrote:
: > : I already write code like this:
: >
: > : #define OVERRIDE
: >
: > : struct der : base {
: > :     OVERRIDE void foo ();
: > : };
: >
: > : then if override can go into C++ X0, I'll change the define to:
: >
: > : #define OVERRIDE override
: >
: > You can always write
: >
: > struct der : base {
: >    /*override*/ void foo ();
: > };
: >
: > To cleanly achieve the same goal.
: >

: It achieves the same goal if the macro is to be used only in one place.
: If it is used all over the source code, you will have to search every
: possible file for '/*override*/' .... whereas the macro's definition may
: be placed in an included header file.

The cost of the change it trivial. It could have been potentially large
if there were risk of not changing something that you should have changed,
or erroneously changing something that you shouldn't have. None
of those risks is present in this case.

Oleg.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/02/21
Raw View
Christopher Eltschka wrote:
...
> Well, the return type is not redundand, given that (a) the declaration
> and the definition need not be in the same file and (b) the return type
> does matter in the definition as well as where used (and usually only
> the declaration is available).

You should always #include the header file declaring a function
prototype, in the file where the function is defined; otherwise, how can
you be sure that prototype and definition match? The claim that the
return type of a function is redundant in the definition, was base upon
the assumption that the function prototype was in scope.

>
> Example:
>
> // file general.h:
>
> class A {};
> class B { B(A); }
> class C { C(B); }

To apply to this argument, general.h should include:

 B f();

>
> ----------------------
> // file with definition:
>
> #include "general.h"
>

With the prototype in scope, the 'B' in the following definition is
redundant, because their is no return type other than 'B' which could
legally be put there.

> B f()
> {
>   A a;
>   return a; // B::B(A) must be called; would not be known
>             // without knowing return type
> }
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/02/19
Raw View
Valentin Bonnard <bonnardv@pratique.fr> wrote:
: I already write code like this:

: #define OVERRIDE

: struct der : base {
:     OVERRIDE void foo ();
: };

: then if override can go into C++ X0, I'll change the define to:

: #define OVERRIDE override


You can always write

struct der : base {
   /*override*/ void foo ();
};

To cleanly achieve the same goal.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1998/02/19
Raw View
Steve Clamage <clamage@Eng.sun.com> wrote in article
<6c4qqf$bd6@engnews1.Eng.Sun.COM>...
> David R Tribble <david.tribble@central.beasys.com> writes:
>
> >We already have to specify redundant 'const' modifiers on member funcs.
>
> I don't think there are any instances of redundant 'const' modifiers
> on member functions. You can overload on const, so omitting it
> on the definition would imply a different function was being
> defined. Two examples:
[SNIP]
> In either case I don't see how it could be considered an
> advantage to allow omitting the const even when it would
> not create an ambiguity. It would not create a problem for
> the compiler, but it would make programs much harder for
> people to read.

I would be wholly against omitting the "const" even where no ambiguity would be
introduced.  Me reason ?  I see the "const" as tagging the hidden argument
"this", and so I want to treat it consistently with the other arguments.

 -- chris
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1998/02/19
Raw View
Valentin Bonnard <bonnardv@pratique.fr> wrote:
> I would like to have a keyword override:
>
> struct base {
>     virtual void foo ();
> };
>
> struct der : base {
>     override void foo ();
> };
>
> It would on be well-formed when declating a overriding a function.

This would get to be a real nuisance if -- like me -- you do a lot of moving
methods around while designing classes.  Since I prefer to design by writing
compilable .h files your keyword would act as a considerable disincentive to
exploratory refactoring.

Also it introduces a new keyword instead of making an existing one work a bit
harder.

 -- chris
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1998/02/19
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> Well, the return type is not redundand, given that (a) the declaration
> and the definition need not be in the same file and (b) the return type
> does matter in the definition as well as where used (and usually only
> the declaration is available).
[perfectly good examples snipped]

It *is* redundant in the method definition.  It is *necessary* in the class
definition (as your examples correctly show), but the information is redundant
at the point where the method is defined since it only echoes what the compiler
has already seen while parsing the class definition.

This applies to ordinary function calls too: if a definition has been seen then
the return type is redundant.  Of course, if no separate declaration has been
seen then there can be no redundancy and the information *must* be provided.

Actually I think this makes a good case for preferring the "always provide
everything" option to the "always omit the redundant information" one.

> Could you show me an implementation of a virtual member function which
> you won't understand if you don't know that it is virtual?

class base
{
   public:
      virtual bool precheckAction();
      void Action();
  private:
      virtual void doAction();
};

void
base::Action()
{
   if (!checkAction())
      throw ...;
   doAction();
}

/* virtual */ bool
base::precheckAction()
{
   return true; // why not "false" ?
}

/* virtual */ void
base::doAction()
{
    // what the f*** is this for ?
}

I contend that the bodies of base::precheckAction() and base::doAction() are
not comprehensible without knowing that they are virtual and designed to be
overridden.

 -- chris


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1998/02/10
Raw View
Kirk Odle <kodle@ghg.net> wrote in article <34ddf1ad.0@news.ghgcorp.com>...
> kartik@ruksun.com wrote in message <6bedml$9na$1@nnrp2.dejanews.com>...
> >I have a question to ask about the virtual keyword.  Why was it decided that
> >virtual keyword should appear with a method's declaration but not with the
> >definition?
[snip]
> Since every module that might need perform dynamic binding of functions
> to objects of a class needs the virtual table index for the bound
> functions, the declarations associated with those functions can be
> declared virtual no later than the class definit ion itself.  The
> presence of the virtual keyword in an out-of-class-definition function
> definition would, at best, be redundant. If it had been required, the
> absense of the keyword in such a definition would not have an obvious
> meaning.  The presence would serve no purpose.


Yes, but can't the same be said of the return type of the method too ?  There
is no *need* to repeat it, but the repetition is deemed (correctly in my view)
to be valuable.

The handling of "virtual" and "static" has always stuck me as a gratuitious
inconsistancy.  Irritating in practise too because it makes it harder to
cut-and-paste method headers from the class definition to the implementation
file.

 -- chris


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: thegoat4@airmail.net (Bryant Brandon)
Date: 1998/02/10
Raw View
In article <6bedml$9na$1@nnrp2.dejanews.com>, kartik@ruksun.com wrote:

[...]

>One reason why I would love to have it is that without referring to the
>header
>file, I can find out if a method is virtual or not.

   That sounds good, similar to the redundant 'auto' keyword--useful for
documentation, but otherwise superfluous.

>Kartikeya G. Rindani
>Ruksun Software Technologies
>(http://www.ruksun.com)

B.B.       --I am not a goat!
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: JHB NIJHOF <nijhojhb@barney.aston.ac.uk>
Date: 1998/02/11
Raw View
Chris Uppal <chris.uppal@ait.REMOVE-THIS.co.uk> wrote:
: Kirk Odle <kodle@ghg.net> wrote in article <34ddf1ad.0@news.ghgcorp.com>...
: > kartik@ruksun.com wrote in message <6bedml$9na$1@nnrp2.dejanews.com>...
: > >I have a question to ask about the virtual keyword.  Why was it decided that
: > >virtual keyword should appear with a method's declaration but not with the
: > >definition?
: [snip]
: > Since every module that might need perform dynamic binding of functions
: > to objects of a class needs the virtual table index for the bound
: > functions, the declarations associated with those functions can be
: > declared virtual no later than the class definit ion itself.  The
: > presence of the virtual keyword in an out-of-class-definition function
: > definition would, at best, be redundant. If it had been required, the
: > absense of the keyword in such a definition would not have an obvious
: > meaning.  The presence would serve no purpose.


: Yes, but can't the same be said of the return type of the method too ?  There
: is no *need* to repeat it, but the repetition is deemed
: (correctly in my view) to be valuable.

There is a need to repeat it: a function `T f() const'
returns a `T const', which differs from the object returned
by `T f()': you can overload on different const-ness, for instance.
So declaring a function 'T f() const' and defining it
as 'T f()' is about the same as declaring a function 'int f()'
and defining it as 'char* f()'.

The situation is different for virtualness: dat doesn't do anything
to the return type.

Jeroen Nijhof


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: marcodg@vcd.hp.com (Marco Dalla Gasperina)
Date: 1998/02/11
Raw View
In article <6bs35j$n7p$1@whatsit.aston.ac.uk>, JHB NIJHOF <nijhojhb@barney.aston.ac.uk> wrote:

>There is a need to repeat it: a function `T f() const'

This is illegal unless f() is a member function.

>returns a `T const',

It returns a T.  The const keyword says that for

class X {
public:
    T f() const;
    T f();
};

'X::f() const' may be called for const X;

>                       which differs from the object returned
>by `T f()'

Both functions return a non-const object of type T.
const T f();
will return an object of type const T.

>           : you can overload on different const-ness, for instance.
>So declaring a function 'T f() const' and defining it
>as 'T f()' is about the same as declaring a function 'int f()'
>and defining it as 'char* f()'.

No, you can't overload only on return type as the return type
is not part of the signature.

Yes, you can overload on constness, but that means (given
the above definition):

X  a;
const X b;

T t1 = a.f(); // calls X::f()
T t2 = b.f(); // calls X::f() const

marco


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/02/12
Raw View
JHB NIJHOF wrote in message <6bs35j$n7p$1@whatsit.aston.ac.uk>...

>There is a need to repeat it: a function `T f() const'
>returns a `T const', which differs from the object returned
>by `T f()': you can overload on different const-ness, for instance.
>So declaring a function 'T f() const' and defining it
>as 'T f()' is about the same as declaring a function 'int f()'
>and defining it as 'char* f()'.


Yes and no.  You can overload based on the difference in constness of a
function or parameter, but no aspect of a difference in return type is
considered in overloading or overriding.

I believe there is some validity to an argument that the return type of
a function has a semantic relevance in a definition.  Virtualness has
none. If, instead of accepting the argument that return types and
virtualness have different roles in this regard, we insist that one or
the other be changed for the sake of coherence, I haven't seen a clue,
let alone a valid argument that it is the virtual keyword rather than
the return type that should be changed.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Chris Uppal" <chris.uppal@ait.REMOVE-THIS.co.uk>
Date: 1998/02/12
Raw View
Kirk Odle <kodle@ghg.net> wrote:
> I believe there is some validity to an argument that the return type of
> a function has a semantic relevance in a definition.  Virtualness has
> none. If, instead of accepting the argument that return types and
> virtualness have different roles in this regard, we insist that one or
> the other be changed for the sake of coherence, I haven't seen a clue,
> let alone a valid argument that it is the virtual keyword rather than
> the return type that should be changed.

It depends on how much emphasis you put on the practicalities.

I'd say that in theory it makes no difference which way the decision goes, as
long as it is consistant.  I.e. *all* redundant information should be restated,
or *none*.

I would prefer to go the "all" route for the pragmatic reason that I don't want
to look in two places while I'm reading or writing the code for the method
definition.  I've already noted that it also makes "seeding" a new .CPP (or
whatever) file by cut-and-paste somewhat easier (I recently spent about three
days doing this, so I'm a a bit sensitive about the subject -- and, yes, I did
automate what I could).

Extending the same point: the meaning of a virtual function is different from a
non-virtual one, hence it is easier to understand the code for the virtual one
if you *know* that it is virtual, and hence know more about its intended
pattern of use.  The same thing goes for static methods.  In short, I don't
agree that "Virtualness has no[ semantic relevance]".

Actually I would go further still and prefer that the language insisted that it
was an error to override a virtual method with one that was not itself
explicitily declared virtual.  Is there some technical reason why this would be
a bad idea ?

Of course, there is the opposite point that this would all be adding extra
verbosity, and that C/C++ have traditionally preferred to maximise brevity.
Personally I'd be quite happy to gain this benefit instead of the ones I've
mentioned above, but as things currently stand I gain neither the extra
clarity, nor the extra brevity.

 -- chris
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1998/02/14
Raw View
Kirk Odle <kodle@ghg.net> wrote:
>> I believe there is some validity to an argument that the return type
>> of a function has a semantic relevance in a definition.  Virtualness
>> has none. If, instead of accepting the argument that return types and
>> virtualness have different roles in this regard, we insist that one
>> or the other be changed for the sake of coherence, I haven't seen a
>> clue, let alone a valid argument that it is the virtual keyword
>> rather than the return type that should be changed.

Chris Uppal wrote:
> It depends on how much emphasis you put on the practicalities.
>
> I'd say that in theory it makes no difference which way the decision
> goes, as long as it is consistant.  I.e. *all* redundant information
> should be restated, or *none*.
>
> I would prefer to go the "all" route for the pragmatic reason that I
> don't want to look in two places while I'm reading or writing the code
> for the method definition.
> ...
>
> Of course, there is the opposite point that this would all be adding extra
> verbosity, and that C/C++ have traditionally preferred to maximise brevity.
> Personally I'd be quite happy to gain this benefit instead of the ones I've
> mentioned above, but as things currently stand I gain neither the extra
> clarity, nor the extra brevity.

We already have to specify redundant 'const' modifiers on member funcs.
But we don't have to specify redundant '= 0' (pure), 'virtual', and
'static' modifiers.  So, yes, there are some inconsistencies in the
language.

Consider the ramifications, given actual code:

    class Foo
    {
        static void     staticFunc();
        int             constFunc() const;
        virtual int     virtFunc();
        virtual int     vcFunc() const;
        virtual void    pureFunc() = 0;
    };

The following are the definitions of the functions above with the
"redundant" specifiers:

    static void Foo::staticFunc()       // Explicit 'static'
    { ... }                             // (but see below)

    int Foo::constFunc() const          // No change,
    { ... }                             // 'const' is already explicit

    virtual int Foo::virtFunc()         // Explicit 'virtual'
    { ... }

    virtual int Foo::vcFunc() const     // Explicit 'virtual'
    { ... }

    virtual void Foo::pureFunc() = 0    // Explicit '= 0'
    { ... }

I don't have a problem with any of these except the last one.
But then, I've always thought the 'pure' specifier looked ugly;
I'd prefer syntax like '= NULL' or a keyword like 'deferred'.

The only conflict these have with existing syntax is the use of the
explicit/redundant 'static'.  This conflicts with the meaning of
'static' for non-member file-scope-only functions.  FWIW, I made
just this proposal some months back, and all of the objections
were arguments along this line - that it conflicted with existing
syntax and semantics.

But I pointed out that since the compiler knows that a class name
prefix (Foo::) is used in the function definition, it would know
that a 'static' modifier meant class-static and not file-static.
But most of those who objected weren't convinced.

Another alternative syntax, which isn't quite as pleasing, would be
to place the "redundant" modifiers after the prototype rather than
before:

    void Foo::staticFunc() static
    { ... }

    int Foo::constFunc() const          // As before
    { ... }

    int Foo::virtFunc() virtual
    { ... }

    int Foo::vcFunc() virtual const
    { ... }

This causes no conflicts with existing syntax, but isn't as pleasing
because the definitions look different from the declarations.

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1998/02/14
Raw View
JHB NIJHOF wrote:
>
> Chris Uppal <chris.uppal@ait.REMOVE-THIS.co.uk> wrote:
> : Kirk Odle <kodle@ghg.net> wrote in article <34ddf1ad.0@news.ghgcorp.com>...
...
> : > declared virtual no later than the class definit ion itself.  The
> : > presence of the virtual keyword in an out-of-class-definition function
> : > definition would, at best, be redundant. If it had been required, the
> : > absense of the keyword in such a definition would not have an obvious
> : > meaning.  The presence would serve no purpose.
>
> : Yes, but can't the same be said of the return type of the method too ?
> : There is no *need* to repeat it, but the repetition is deemed
> : (correctly in my view) to be valuable.
>
> There is a need to repeat it: a function `T f() const'
> returns a `T const', which differs from the object returned
> by `T f()': you can overload on different const-ness, for instance.
> So declaring a function 'T f() const' and defining it
> as 'T f()' is about the same as declaring a function 'int f()'
> and defining it as 'char* f()'.

You cannot overload a function on return type (unless they've made
another change I didn't notice). The 'const' in "T myclass::f() const"
refers to the myclass object, not the T object. Therefore, the return
type of a function definition is technically redundant if the
appropriate function prototype is in scope; this redundancy serves the
useful purpose of providing validity checks. Allowing the 'virtual'
keyword in function definitions would improve the validity checking.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/02/14
Raw View
On 12 Feb 98 11:51:20 GMT, "Chris Uppal"
<chris.uppal@ait.REMOVE-THIS.co.uk> wrote:

>Actually I would go further still and prefer that the language insisted that it
>was an error to override a virtual method with one that was not itself
>explicitily declared virtual.  Is there some technical reason why this would be
>a bad idea ?

It's seeming less and less a bad idea to me, considering the following
is apparently legal:

 template<class T> struct A {};
 template<class T> struct B : A<T>
 {
    void fun();
 };
 template<> struct A<char>
 {
    virtual void fun();
 };

 void fun(A<char>* p)
 {
    // If p points to a B<char>, calls B<char>::fun!
    p->fun();
 }

 fun(new B<char>);

Somehow, I don't think the designer of B<T> is expecting his fun to
override A<T>'s, which is most likely non-existent from B<T>'s
designer's point of view. I tend to think this is simply the kind of
thing a specializer of A needs to avoid doing, but I'd be interested
to hear of a case where it's reasonable.

--
Doug Harrison
dHarrison@worldnet.att.net


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/02/16
Raw View
>You cannot overload a function on return type (unless they've made
>another change I didn't notice). The 'const' in "T myclass::f() const"
>refers to the myclass object, not the T object. Therefore, the return
>type of a function definition is technically redundant if the
>appropriate function prototype is in scope; this redundancy serves the
>useful purpose of providing validity checks. Allowing the 'virtual'
>keyword in function definitions would improve the validity checking.

Whether it would improve validity checking or not has not been clearly
established, merely asserted.  Nothing prevents you from providing
information about a function's virtualness in a code comment. The
current arrangement allows functions to be self-maintaining in terms
of changes of virtualness. The new feature will not substantially
improve checking unless the absence of the keyword in a definition is
treated as an error.  This will break every existing extra-class
virtual function definition in existence. Are you going to pay for my
organization's labor to update our existing code out of your own
pocket?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.sun.com (Steve Clamage)
Date: 1998/02/16
Raw View
David R Tribble <david.tribble@central.beasys.com> writes:

>We already have to specify redundant 'const' modifiers on member funcs.

I don't think there are any instances of redundant 'const' modifiers
on member functions. You can overload on const, so omitting it
on the definition would imply a different function was being
defined. Two examples:

 struct T {
  int f(const int*);
 };
 int T::f(int*) { ... } // error
We don't allow this code because T has no declared member taking
a pointer to non-const int. But we could add an additional
function f which did so.

 struct U {
  int f() const;
 };
 int U::f() { ... } // error
Once again, we don't allow this code because U has no declared
member taking a non-const object parameter. But we could add an
additional function f which did so.

In either case I don't see how it could be considered an
advantage to allow omitting the const even when it would
not create an ambiguity. It would not create a problem for
the compiler, but it would make programs much harder for
people to read.
--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/02/16
Raw View
Chris Uppal <chris.uppal@ait.REMOVE-THIS.co.uk> writes:

> Actually I would go further still and prefer that the language insisted
> that it was an error to override a virtual method with one that was not
> itself explicitily declared virtual.  Is there some technical reason why
> this would be a bad idea ?

I would like to have a keyword override:

struct base {
    virtual void foo ();
};

struct der : base {
    override void foo ();
};

It would on be well-formed when declating a overriding a function.

I already write code like this:

#define OVERRIDE

struct der : base {
    OVERRIDE void foo ();
};

then if override can go into C++ X0, I'll change the define to:

#define OVERRIDE override

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/02/16
Raw View
I'm still not satisified that the extra-class virtual declaration serves a
practical
purpose.  After all, is it that important to a programmer looking at the
definition
of a function to know that the function is virtual? If so, I would insist
that the
programmer is beginning to work with the function intimately.  Surely he
will
need to know the types of member data as well. Are we to litter the source
code
with compiler-validated references to these as well?

If we allow this use of the keyword, do we also require the compiler to
complain
should it be absent? What do we do about all the millions of lines of code
that
is not compliant? What use is this aspect of the keyword if it is not
enforced by
the compiler? What prevents the developer or his organizations from
providing
this function metadata in a function comment prolog?

David R Tribble wrote in message <34E47E3F.7305@central.beasys.com>...
>Kirk Odle <kodle@ghg.net> wrote:
>>> I believe there is some validity to an argument that the return type
>>> of a function has a semantic relevance in a definition.  Virtualness
>>> has none. If, instead of accepting the argument that return types and
>>> virtualness have different roles in this regard, we insist that one
>>> or the other be changed for the sake of coherence, I haven't seen a
>>> clue, let alone a valid argument that it is the virtual keyword
>>> rather than the return type that should be changed.
>
>Chris Uppal wrote:
>> It depends on how much emphasis you put on the practicalities.
>>
>> I'd say that in theory it makes no difference which way the decision
>> goes, as long as it is consistant.  I.e. *all* redundant information
>> should be restated, or *none*.
>>
>> I would prefer to go the "all" route for the pragmatic reason that I
>> don't want to look in two places while I'm reading or writing the code
>> for the method definition.
>> ...
>>
>> Of course, there is the opposite point that this would all be adding
extra
>> verbosity, and that C/C++ have traditionally preferred to maximise
brevity.
>> Personally I'd be quite happy to gain this benefit instead of the ones
I've
>> mentioned above, but as things currently stand I gain neither the extra
>> clarity, nor the extra brevity.
>
>We already have to specify redundant 'const' modifiers on member funcs.
>But we don't have to specify redundant '= 0' (pure), 'virtual', and
>'static' modifiers.  So, yes, there are some inconsistencies in the
>language.
>
>Consider the ramifications, given actual code:
>
>    class Foo
>    {
>        static void     staticFunc();
>        int             constFunc() const;
>        virtual int     virtFunc();
>        virtual int     vcFunc() const;
>        virtual void    pureFunc() = 0;
>    };
>
>The following are the definitions of the functions above with the
>"redundant" specifiers:
>
>    static void Foo::staticFunc()       // Explicit 'static'
>    { ... }                             // (but see below)
>
>    int Foo::constFunc() const          // No change,
>    { ... }                             // 'const' is already explicit
>
>    virtual int Foo::virtFunc()         // Explicit 'virtual'
>    { ... }
>
>    virtual int Foo::vcFunc() const     // Explicit 'virtual'
>    { ... }
>
>    virtual void Foo::pureFunc() = 0    // Explicit '= 0'
>    { ... }
>
>I don't have a problem with any of these except the last one.
>But then, I've always thought the 'pure' specifier looked ugly;
>I'd prefer syntax like '= NULL' or a keyword like 'deferred'.
>
>The only conflict these have with existing syntax is the use of the
>explicit/redundant 'static'.  This conflicts with the meaning of
>'static' for non-member file-scope-only functions.  FWIW, I made
>just this proposal some months back, and all of the objections
>were arguments along this line - that it conflicted with existing
>syntax and semantics.
>
>But I pointed out that since the compiler knows that a class name
>prefix (Foo::) is used in the function definition, it would know
>that a 'static' modifier meant class-static and not file-static.
>But most of those who objected weren't convinced.
>
>Another alternative syntax, which isn't quite as pleasing, would be
>to place the "redundant" modifiers after the prototype rather than
>before:
>
>    void Foo::staticFunc() static
>    { ... }
>
>    int Foo::constFunc() const          // As before
>    { ... }
>
>    int Foo::virtFunc() virtual
>    { ... }
>
>    int Foo::vcFunc() virtual const
>    { ... }
>
>This causes no conflicts with existing syntax, but isn't as pleasing
>because the definitions look different from the declarations.
>
>-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/02/16
Raw View
Chris Uppal wrote:
>
> Kirk Odle <kodle@ghg.net> wrote:
> > I believe there is some validity to an argument that the return type of
> > a function has a semantic relevance in a definition.  Virtualness has
> > none. If, instead of accepting the argument that return types and
> > virtualness have different roles in this regard, we insist that one or
> > the other be changed for the sake of coherence, I haven't seen a clue,
> > let alone a valid argument that it is the virtual keyword rather than
> > the return type that should be changed.
>
> It depends on how much emphasis you put on the practicalities.
>
> I'd say that in theory it makes no difference which way the decision goes, as
> long as it is consistant.  I.e. *all* redundant information should be restated,
> or *none*.
>

Well, the return type is not redundand, given that (a) the declaration
and the definition need not be in the same file and (b) the return type
does matter in the definition as well as where used (and usually only
the declaration is available).

Example:

// file general.h:

class A {};
class B { B(A); }
class C { C(B); }

----------------------
// file with definition:

#include "general.h"

B f()
{
  A a;
  return a; // B::B(A) must be called; would not be known
            // without knowing return type
}

// file with declaration:

B f();

int main()
{
  C c(f()); // C::C(B) must be called; would not be known
            // without knowing return type
}

Now you could argue that for member function definitions, you
must have the class definition visible, which in turn contains
the member declaration. But would you really like different
definitions for normal and member functions?

> I would prefer to go the "all" route for the pragmatic reason that I don't want
> to look in two places while I'm reading or writing the code for the method
> definition.  I've already noted that it also makes "seeding" a new .CPP (or
> whatever) file by cut-and-paste somewhat easier (I recently spent about three
> days doing this, so I'm a a bit sensitive about the subject -- and, yes, I did
> automate what I could).
>

Ease of editing is of course a valid point. (One could, however, argue
that your tools should help you here.)

> Extending the same point: the meaning of a virtual function is different from a
> non-virtual one, hence it is easier to understand the code for the virtual one
> if you *know* that it is virtual, and hence know more about its intended
> pattern of use.  The same thing goes for static methods.  In short, I don't
> agree that "Virtualness has no[ semantic relevance]".

Could you show me an implementation of a virtual member function which
you won't understand if you don't know that it is virtual?
Also, you could be using the class itself, or a derived class which
doesn't override the function (even if it is pure virtual, the derived
class could simply call the base class version).

>
> Actually I would go further still and prefer that the language insisted that it
> was an error to override a virtual method with one that was not itself
> explicitily declared virtual.  Is there some technical reason why this would be
> a bad idea ?

In this point, I agree. I don't see any reason why this shouldn't
be required. Note that in Borland Pascal with Objects you do have this
requirement (but no "virtual" on definition, again), and I've never
seen a problem with this.
It also would enable the compiler to catch some errors:

// library header

class Whatever
{
// no do_something method here
};

// your program:

#include "library header"

class X: public Whatever
{
  void do_something();
};

// next version of library header

class Whatever
{
  virtual void do_something();
      // oops! this breaks your code when switching! No warning given...
};

>
> Of course, there is the opposite point that this would all be adding extra
> verbosity, and that C/C++ have traditionally preferred to maximise brevity.
> Personally I'd be quite happy to gain this benefit instead of the ones I've
> mentioned above, but as things currently stand I gain neither the extra
> clarity, nor the extra brevity.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/02/17
Raw View
Kirk Odle wrote:
...
> >useful purpose of providing validity checks. Allowing the 'virtual'
> >keyword in function definitions would improve the validity checking.
>
> Whether it would improve validity checking or not has not been clearly
> established, merely asserted.  Nothing prevents you from providing
> information about a function's virtualness in a code comment. The

The compiler wiil ignore that comment, making it less useful than the
original suggestion.

> current arrangement allows functions to be self-maintaining in terms
> of changes of virtualness. The new feature will not substantially
> improve checking unless the absence of the keyword in a definition is
> treated as an error.  This will break every existing extra-class
> virtual function definition in existence. Are you going to pay for my
> organization's labor to update our existing code out of your own
> pocket?

There are three different ways to implement a validity check of this
kind. On code where the definition of a member function is seperated
from the declaration, either require the 'virtual' modifier on the
definition if it is also on the declaration, or prohibit the 'virtual'
modifier if it is not on also on the declaration, or both. Since the
'virtual' keyword is not currently permitted on seperated definitions,
no existing code would be broken by the second option. Any one of the
three options would improve the validity checking. However, I'm not
prepared to argue the that advantages are sufficient to justify the
change. I'm merely pointing out that the change wouldn't be pointless.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Kirk Odle" <kodle@ghg.net>
Date: 1998/02/09
Raw View
kartik@ruksun.com wrote in message <6bedml$9na$1@nnrp2.dejanews.com>...
>I have a question to ask about the virtual keyword.  Why was it decided that
>virtual keyword should appear with a method's declaration but not with the
>definition?

The compiler obtains two key kinds of information about objects of a
class from the class declaration. The first is which functions have
special access to data and function members of the object.  The second
is information about the physical layout of objects of the class and
logical makeup of data that support the class itself.  Each item in a
class declaration serves one or both of these purposes. Functions that
are declared virtual in a class definition fall in both of these
categories; they have to do with membership and physical layout.

Virtual functions implement dynamic binding (the selection of an
operation at runtime based on a specific function's type).  While the
C++ standard does not specify a particular model for how to implement
dynamic binding, there is a practical model that is useful for purposes
of this discussion.  A virtual function declaration is associated with
the reservation of a function address in a "virtual table." Dynamically
bound calls to functions are represented by an index in the appropriate
class' virtual table and the address of the table itself.  The address
of the virtual table is stored as a pointer in every object that
belongs to a class.  When dynamic binding occurs (and there are
specific rules determining when it will occur), the virtual table
address is obtained from the virtual table pointer in the object, the
index of the function, having been provided by the compiler, is used to
calculate an address that contains the address of the function to be
called.

Since every module that might need perform dynamic binding of functions
to objects of a class needs the virtual table index for the bound
functions, the declarations associated with those functions can be
declared virtual no later than the class definit ion itself.  The
presence of the virtual keyword in an out-of-class-definition function
definition would, at best, be redundant. If it had been required, the
absense of the keyword in such a definition would not have an obvious
meaning.  The presence would serve no purpose.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Abhay Kanhere <abhay@hp11.cpdc.ece.nwu.edu>
Date: 1998/02/09
Raw View
kartik@ruksun.com writes:

> I have a question to ask about the virtual keyword.  Why was it decided that
> virtual keyword should appear with a method's declaration but not with the
> definition?
 One reason might be, that when you release a library, you
are expected to make only interfaces available. Since no format was
defined for layout of compiled objects and placing information in the
compiled  object about its methods - for space efficiency, the only
interface of compiled code it its header.
  Since while compiling code that uses these libraries the
compiler needs to setup/use the vtbl or equivalent, this
'virtual-ness' information has to be present in an accessible form.
 Otherwise, 'detecting  virtual-ness' becomes an across source-files
search. Which is very inefficient.


 - Abhay
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Loic Tregan <Loic.Tregan@cert.fr>
Date: 1998/02/09
Raw View
kartik@ruksun.com wrote:
>
> I have a question to ask about the virtual keyword.  Why was it decided that
> virtual keyword should appear with a method's declaration but not with the
> definition?
>
> E.g.
> // X.H
> class X
> {
>    virtual void foo();
> };
>
> // X.CPP
>
> virtual void X::foo()
> ^^^^^^^
> {
> }
>

  this specification would be coherent with the usage of 'const' (wich
must be provided - at least with my version of CC - both in the
declaration and the definition of the function)


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Phlip <tegan@deltanet.com>
Date: 1998/02/10
Raw View
kartik@ruksun.com escribi=F3:

> I have a question to ask about the virtual keyword.  Why was it decided=
 that
> virtual keyword should appear with a method's declaration but not with =
the
> definition?

Because keywords are a precious resource and difficult to add to a langua=
ge
(unless you are Perl, where all variables are marked by $).

A language should lock out all stray uses of a keyword that add no value.=
 This
preserves existing keywords for some possible future meaning without brea=
king
existing code. Consider how 'static' has one meaning, but many uses. If s=
omebody
thought of a use for 'virtual' outside a class definition, the keyword ca=
n take
this new meaning without changing its current meaning or adding a new key=
word.

> One reason why I would love to have it is that without referring to the
> header
> file, I can find out if a method is virtual or not.

As a coding style, just say

    //  virtual
    void
Pad::Rino ()  {..

but it would be nice if LINT were extendible to check this kind of thing.=
..

  --  Phlip
=3D=3D=3D=3D=3D=3D=3D http://users.deltanet.com/~tegan/home.html =3D=3D=3D=
=3D=3D=3D=3D
  --  Spacetime is money  --
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/02/10
Raw View
In article 7205@cert.fr, Loic Tregan <Loic.Tregan@cert.fr> writes:
>kartik@ruksun.com wrote:
>>
>> I have a question to ask about the virtual keyword.  Why was it decided that
>> virtual keyword should appear with a method's declaration but not with the
>> definition?
>
>  this specification would be coherent with the usage of 'const' (wich
>must be provided - at least with my version of CC - both in the
>declaration and the definition of the function)

The two situations are not comparable. You can overload on const, but
not on virtual, so the const is necessary to determine which function
is being defined. Example:

    struct T {
 int f1() const;
 int f1(); // overloaded on const
 int f2(int) const;
 int f3();
    };

    int T::f1() { ... }    // this is not the const version
    int T::f2(int) { ... } // error, no non-const version declared
    int T::f3(int) { ... } // error, no f3(int) declared

The definition of f2 is in error for the same reason as that of f3:
no such function was declared in the class.

Requiring virtual on the definition seemed like an unnecessary
redundancy. It adds no type safety, for example.

>> One reason why I would love to have it is that without referring to the
>> header
>> file, I can find out if a method is virtual or not.

This part I don't understand. If you are a client of the class, surely
you are not looking at the class implementation INSTEAD of the header.
If you are implementing the class, surely you need to keep the
header readily available anyway.

---
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: kartik@ruksun.com
Date: 1998/02/06
Raw View
I have a question to ask about the virtual keyword.  Why was it decided that
virtual keyword should appear with a method's declaration but not with the
definition?

E.g.
// X.H
class X
{
   virtual void foo();
};

// X.CPP

virtual void X::foo()
^^^^^^^
{
}

One reason why I would love to have it is that without referring to the
header
file, I can find out if a method is virtual or not.

Kartikeya G. Rindani
Ruksun Software Technologies
(http://www.ruksun.com)

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]