Topic: Defect Report: cv qualifiers on function types


Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 30 Jul 2001 17:29:07 GMT
Raw View
In article <9jt87j$2lq$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>Ah so!  Thanks for pointing that out.
>
>I remain confused on one point:  why are we not in violation of
>2.95.3, Paragraph 4, which AFIK states:
>
>   In fact, if at any time in the determination of a type a
>   cv-qualified function type is formed, the program is ill-formed.
>
>Doesn't "const X foo(...) const;" have a cv-qualified function type?

No, that second const refer to the 'this' parameter. A cv qualified
function type would be something like that produced by

typedef void (const*fn)();

And it requires some contortions to achieve this other than through a
typedef.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Fri, 27 Jul 2001 17:33:46 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9jnuqb$cqc$2@glue.ucr.edu>, thp@cs.ucr.edu writes
:>: class X {
:>: public:
:>:    X foo();
:>:    X const foo()const;
:>:    void bar();
:>: // other
:>: };
:>
:>: int main(){
:>:   X x;
:>:   X const xc;
:>:   x.foo().bar();  // fine
:>:   xc.foo().bar();  // error
:>: }
:>
:>: Enough help?
:>
:>I'm not sure.  (I seem to need a lot of help on this one.)

: The important feature is that when a class instance is returned by value
: the specified cv qualification determines which of the class member
: functions can be called.

The overloading of foo confused me.  I was of the (possibly mistaken)
impression that overloading is strictly signature driven, and that the
type of the return value (including qualifications) is irrelevant.

: If you return just the value, all accessible
: member function can be called on the return value, if it is const
: qualified only const (and const volatile) members can be called.

Your subsequent example seems to demonstrate that perfectly.

: This comes as a deep shock to many programmers who assume that const
: qualification on a return by value is meaningless (I know because Scott
: Meyers had to explain it to me long after I should have known:)

I learned something new, thanks to your persistence.

:>: Note it is the const in the return that makes the
:>: difference to whether bar can be called on the return value of the
:>: selected foo().

:>Hmmmm.  g++ complains that xc is already nonaggregate, so I can't even
:>call foo() on it.  (But I don't understand that either.)

: You did include the second const?

Yes.  But you failed to initialize xc, and I attempted to initialize
it via:

    X const xc();  // Oops!

instead of:

    X const xc = X();  // the right way.

Thanks again.

Tom Payne











---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Fri, 27 Jul 2001 17:34:01 GMT
Raw View
John Potter <jpotter@falcon.lhup.edu> wrote:
[...]
: non-const l-value
: const     l-value
: non-const r-value
: const     r-value

: They all exist.

IIRC, James Kanze pointed out to me a couple of years ago that a
struct/class r-value *is* an l-value (and the Standard explicitly says
so somewhere).  For such cases, const makes perfect sense.

I'm not sure how an int r-value could get any more const than it
already is, but allowing const qualification for all types promotes
syntactic and semantic uniformity.

Tom Payne

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Fri, 27 Jul 2001 23:04:36 GMT
Raw View
thp@cs.ucr.edu writes:

|     X const xc();  // Oops!
|
| instead of:
|
|     X const xc = X();  // the right way.

Yeah, syntax does matter :-) :-)

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Matvei Brodski <mbrodski@bear.nospam.com>
Date: Sat, 28 Jul 2001 01:05:34 GMT
Raw View
thp@cs.ucr.edu wrote:

> Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
> : In article <9jnuqb$cqc$2@glue.ucr.edu>, thp@cs.ucr.edu writes
> :>: class X {
> :>: public:
> :>:    X foo();
> :>:    X const foo()const;
> :>:    void bar();
> :>: // other
> :>: };
> :>
> :>: int main(){
> :>:   X x;
> :>:   X const xc;
> :>:   x.foo().bar();  // fine
> :>:   xc.foo().bar();  // error
> :>: }
> :>
> :>: Enough help?
> :>
> :>I'm not sure.  (I seem to need a lot of help on this one.)
>
> : The important feature is that when a class instance is returned by value
> : the specified cv qualification determines which of the class member
> : functions can be called.
>
> The overloading of foo confused me.  I was of the (possibly mistaken)
> impression that overloading is strictly signature driven, and that the
> type of the return value (including qualifications) is irrelevant.

Overloading is signature driven. One thing you are missing is an
implied "this" parameter. Consider how both versions of foo() would
look like if this had to be explicitly mentioned:

X foo( X* this ); // instead of "X foo();"
const X foo( const X* this); // "const X foo() const;"

Now the way the overloading works can be seen by the naked eye.

Matvei.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Sat, 28 Jul 2001 10:06:48 GMT
Raw View
thp@cs.ucr.edu writes:

| John Potter <jpotter@falcon.lhup.edu> wrote:
| [...]
| : non-const l-value
| : const     l-value
| : non-const r-value
| : const     r-value
|=20
| : They all exist.
|=20
| IIRC, James Kanze pointed out to me a couple of years ago that a
| struct/class r-value *is* an l-value (and the Standard explicitly says
| so somewhere).  For such cases, const makes perfect sense. =20

That is not quite right.  Given

 struct X { };

The Standard does explicitly say that the expression  =AB X() =BB is -not=
-
an lvalue -- see 3.10.

However, inside a member function invoked for an rvalue of class type
*this designates an lvalue.

--=20
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 30 Jul 2001 03:16:55 GMT
Raw View
Matvei Brodski <mbrodski@bear.nospam.com> wrote:
: thp@cs.ucr.edu wrote:
:>
:> The overloading of foo confused me.  I was of the (possibly mistaken)
:> impression that overloading is strictly signature driven, and that the
:> type of the return value (including qualifications) is irrelevant.

: Overloading is signature driven. One thing you are missing is an
: implied "this" parameter. Consider how both versions of foo() would
: look like if this had to be explicitly mentioned:

: X foo( X* this ); // instead of "X foo();"
: const X foo( const X* this); // "const X foo() const;"

: Now the way the overloading works can be seen by the naked eye.

Ah so!  Thanks for pointing that out.

I remain confused on one point:  why are we not in violation of
2.95.3, Paragraph 4, which AFIK states:

   In fact, if at any time in the determination of a type a
   cv-qualified function type is formed, the program is ill-formed.

Doesn't "const X foo(...) const;" have a cv-qualified function type?

Thanks,
Tom Payne

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 30 Jul 2001 10:31:48 GMT
Raw View
thp@cs.ucr.edu wrote:
...
> I remain confused on one point:  why are we not in violation of
> 2.95.3, Paragraph 4, which AFIK states:

There is no 2.95. The words you cite are from 8.3.5p4.

>    In fact, if at any time in the determination of a type a
>    cv-qualified function type is formed, the program is ill-formed.
>
> Doesn't "const X foo(...) const;" have a cv-qualified function type?

No, the first const qualifies the return type, the second const
qualifies the implicit first argument type. Neither of them qualifies
the function type itself. It's actually fairly hard to qualify a
function type. Direct insertion of 'const' into a function declaration
normally either has a legal interpretation, or is a syntax error before
it ever gets a chance to qualify as ill-formed. The easiest way I can
think of to actually use legal syntax to violate that rule is through
typedefs. That's exactly what they do in the example in that same
section:

    typedef void F();
        struct S{
            const F f; // ill-formed.
                       // not equivalent to: void f() const;
 };

Note that typedefs are not simple text substitutions, so this
declaration is also not equivalent to "const void f()". 'F' acts like a
type in it's own right, so the 'const' qualifies the entire fucntion
type, not just the return type of the function. Qualifying a function
type is a meaningless concept, which is why the program would be
ill-formed.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Wed, 25 Jul 2001 11:08:21 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9jagt1$6tb$1@glue.ucr.edu>, thp@cs.ucr.edu writes
:>So, a function returns an rvalue and rvalues are de facto constant --
:>three isn't going to become four (except in FORTRAN).  Also, the
:>notion of a volatile rvalue seems bizarre but benign.  Why not simply
:>ignore cv-qualifiers both for references and for rvalues?

: Unfortunately for this argument, const qualification on rvalues of user
: defined type is significant because without it non-const member
: functions can be called on an rvalue.

Sorry.  I need some help on that.

Tom Payne








---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 25 Jul 2001 21:19:23 GMT
Raw View
In article <9jloh4$lfe$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>: Unfortunately for this argument, const qualification on rvalues of user
>: defined type is significant because without it non-const member
>: functions can be called on an rvalue.
>
>Sorry.  I need some help on that.

class X {
public:
   X foo();
   X const foo()const;
   void bar();
// other
};

int main(){
  X x;
  X const xc;
  x.foo().bar();  // fine
  xc.foo().bar();  // error
}

Enough help? Note it is the const in the return that makes the
difference to whether bar can be called on the return value of the
selected foo().

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Thu, 26 Jul 2001 05:31:57 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9jloh4$lfe$1@glue.ucr.edu>, thp@cs.ucr.edu writes
:>: Unfortunately for this argument, const qualification on rvalues of user
:>: defined type is significant because without it non-const member
:>: functions can be called on an rvalue.
:>
:>Sorry.  I need some help on that.

: class X {
: public:
:    X foo();
:    X const foo()const;
:    void bar();
: // other
: };

: int main(){
:   X x;
:   X const xc;
:   x.foo().bar();  // fine
:   xc.foo().bar();  // error
: }

: Enough help?

I'm not sure.  (I seem to need a lot of help on this one.)

: Note it is the const in the return that makes the
: difference to whether bar can be called on the return value of the
: selected foo().

Hmmmm.  g++ complains that xc is already nonaggregate, so I can't even
call foo() on it.  (But I don't understand that either.)

Tom Payne















---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Thu, 26 Jul 2001 16:27:54 GMT
Raw View
thp@cs.ucr.edu writes:

| : int main(){
| :   X x;
| :   X const xc;
| :   x.foo().bar();  // fine
| :   xc.foo().bar();  // error
| : }

| Hmmmm.  g++ complains that xc is already nonaggregate, so I can't even
| call foo() on it.  (But I don't understand that either.)

I think g++ probably shocked on xc being const with no
initializer. Try

 X const xc = X();

Hope that helps,

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Thu, 26 Jul 2001 17:51:20 GMT
Raw View
Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> wrote:
: thp@cs.ucr.edu writes:

: | : int main(){
: | :   X x;
: | :   X const xc;
: | :   x.foo().bar();  // fine
: | :   xc.foo().bar();  // error
: | : }

: | Hmmmm.  g++ complains that xc is already nonaggregate, so I can't even
: | call foo() on it.  (But I don't understand that either.)

: I think g++ probably shocked on xc being const with no
: initializer. Try

:  X const xc = X();

: Hope that helps,

That helps.  Thanks.  It now gives the following error:

  passing `const X' as `this' argument of `void X::bar()' discards qualifiers

and produces no a.out.

Could we be violating 2.95.3 Paragraph 4, which states:

     In fact, if at any time in the determination of a type a
     cv-qualified function type is formed, the program is ill-formed.

Tom Payne

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 26 Jul 2001 19:47:08 GMT
Raw View
In article <9jpj9c$rka$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>That helps.  Thanks.  It now gives the following error:
>
>  passing `const X' as `this' argument of `void X::bar()' discards qualifiers
>
>and produces no a.out.
>
>Could we be violating 2.95.3 Paragraph 4, which states:
>
>     In fact, if at any time in the determination of a type a
>     cv-qualified function type is formed, the program is ill-formed.

Possibly I over simplified in trying to produce a minimal example.

Try

class X {
public:
     X const foo();
     X const bar() const;
// rest
};

int main() {
  X x;
  x.foo().bar(); //OK
  x.bar().foo(); // fails
}

Reason: x.foo() returns a X const which can call bar() because that is a
const member

x.bar() also returns a X const but that cannot call foo() because that
is a non-const member.

Trying to provide minimalist code is not always easy (and real life
examples too often confuse the wood for the trees.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Thu, 26 Jul 2001 15:14:12 CST
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> writes:

| Trying to provide minimalist code is not always easy (and real life
| examples too often confuse the wood for the trees.

Frankly, I think got it pretty much right.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 26 Jul 2001 21:13:10 GMT
Raw View
In article <9jnuqb$cqc$2@glue.ucr.edu>, thp@cs.ucr.edu writes
>: class X {
>: public:
>:    X foo();
>:    X const foo()const;
>:    void bar();
>: // other
>: };
>
>: int main(){
>:   X x;
>:   X const xc;
>:   x.foo().bar();  // fine
>:   xc.foo().bar();  // error
>: }
>
>: Enough help?
>
>I'm not sure.  (I seem to need a lot of help on this one.)

The important feature is that when a class instance is returned by value
the specified cv qualification determines which of the class member
functions can be called. If you return just the value, all accessible
member function can be called on the return value, if it is const
qualified only const (and const volatile) members can be called. This
comes as a deep shock to many programmers who assume that const
qualification on a return by value is meaningless (I know because Scott
Meyers had to explain it to me long after I should have known:)

>
>: Note it is the const in the return that makes the
>: difference to whether bar can be called on the return value of the
>: selected foo().
>
>Hmmmm.  g++ complains that xc is already nonaggregate, so I can't even
>call foo() on it.  (But I don't understand that either.)

You did include the second const?



Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 26 Jul 2001 21:19:40 GMT
Raw View
On Thu, 26 Jul 2001 17:51:20 GMT, thp@cs.ucr.edu wrote:

> That helps.  Thanks.  It now gives the following error:
>
>   passing `const X' as `this' argument of `void X::bar()' discards qualifiers
>
> and produces no a.out.

I think that 3.10/10 may explain the confusion.  L-value/r-value and
modifiable/non-modifiable are partly orthoginal.

struct S { };
S const f () { return X(); }
int main () {
   int i; // a modifiable l-value
   i = 5;
   int const& icr(i); // a non-modifiable l-value
   S s;
   f() = s; // error, a non-modifiable r-value
   S() = s; // ok, a modifiable r-value and non-const member operator=
   S const& scr = S(); // a non-modifiable l-value
   S& sr = S();  // error, not allowed
   int() = 5; // error, built-ins do not have members
              // the built-in assignment operator requires an l-value.
   }

The error in the original is that the call of foo on a const object
returned a non-modifiable r-value and the only bar available is a
non-const member.  The prior call of foo on a non-const object returned
a modifiable r-value and the call of bar is acceptable.

non-const l-value
const     l-value
non-const r-value
const     r-value

They all exist.

John

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Mon, 23 Jul 2001 19:23:24 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> writes:

| In article <9jagt1$6tb$1@glue.ucr.edu>, thp@cs.ucr.edu writes
| >So, a function returns an rvalue and rvalues are de facto constant --
| >three isn't going to become four (except in FORTRAN).  Also, the
| >notion of a volatile rvalue seems bizarre but benign.  Why not simply
| >ignore cv-qualifiers both for references and for rvalues?
|
| Unfortunately for this argument, const qualification on rvalues of user
| defined type is significant

Completely agreed.

| because without it non-const member functions can be called on an rvalue.

But that already is the case:

 struct X { };

 int main()
 {
    X x;
    X() = x;

    return 0;
 }

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Sat, 21 Jul 2001 00:06:11 GMT
Raw View
Nathan Sidwell <nathan@codesourcery.com> wrote:
[...]
: [8.3.2] dcl.ref describes references. Of interest is the statement
: (my emphasis)
:  "Cv-qualified references are ill-formed /except/ when
:  the cv-qualifiers are introduced through the use of a typedef
:  or of a template type argument, in which case the cv-qualifiers
:  are ignored".
: Though it is strange to ignore 'volatile' here, that is not the point
: of this defect report. [8.3.5] dcl.fct describes function types.

I would guess that the objection to cv-qualifiers on references is
that const and volatile are attributes of objects and references
aren't objects.  But even if references were objects (say
automatically dereferenced pointers), they are de facto constant and
could behave weirdly if they were really volatile.  So, any const or
volatile qualification is probably an oversight.  But why "undefined
behavior"?  Also, why the exception for these particular cases?

FWIW, my copy of g++ (2.95.3) accepts cv-qualified references but
issues a message noting that the qualifer is being discarded.

: Paragraph 4 states,
:  "In fact, if at any time in the determination of a type a
:  cv-qualified function type is formed, the program is ill-formed."
: No allowance for typedefs or template type parameters is
: made here, which is inconsistent with the equivalent reference case.

So, a function returns an rvalue and rvalues are de facto constant --
three isn't going to become four (except in FORTRAN).  Also, the
notion of a volatile rvalue seems bizarre but benign.  Why not simply
ignore cv-qualifiers both for references and for rvalues?

Tom Payne

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 23 Jul 2001 18:56:43 GMT
Raw View
In article <9jagt1$6tb$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>So, a function returns an rvalue and rvalues are de facto constant --
>three isn't going to become four (except in FORTRAN).  Also, the
>notion of a volatile rvalue seems bizarre but benign.  Why not simply
>ignore cv-qualifiers both for references and for rvalues?

Unfortunately for this argument, const qualification on rvalues of user
defined type is significant because without it non-const member
functions can be called on an rvalue.

Weirdly, the same applies to volatile but I have yet to see a serious
volatile interface provided for a class [a class has 24 interfaces
available (plain, const, volatile, const volatile)x(public, protected,
private)x(virtual, non-virtual)]


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Nathan Sidwell <nathan@codesourcery.com>
Date: 29 Jun 01 14:08:09 GMT
Raw View
 [Moderator's note: this defect report has been
 forwarded to the C++ committee. -moderator(fjh).]

Hi,
this concerns the inconsistent treatment of cv qualifiers on
reference types and function types. The problem originated with
GCC bug report c++/2810. The bug report is available at
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=2810&database=gcc

[8.3.2] dcl.ref describes references. Of interest is the statement
(my emphasis)
 "Cv-qualified references are ill-formed /except/ when
 the cv-qualifiers are introduced through the use of a typedef
 or of a template type argument, in which case the cv-qualifiers
 are ignored".
Though it is strange to ignore 'volatile' here, that is not the point
of this defect report. [8.3.5] dcl.fct describes function types.
Paragraph 4 states,
 "In fact, if at any time in the determination of a type a
 cv-qualified function type is formed, the program is ill-formed."
No allowance for typedefs or template type parameters is
made here, which is inconsistent with the equivalent reference case.

The GCC bug report was template code which attempted to do,

 template <typename T> void foo (T const &);
 void baz ();
 ...
 foo (baz);

in the instantiation of foo, T is `void ()' and an attempt is made to
const qualify that, which is ill-formed. This is a surprise.

Suggested Resolution:
Replace the quoted sentance from paragraph 4 in [8.3.5] with
 "cv-qualified functions are ill-formed, except when the
 cv-qualifiers are introduced through the use of a typedef or of
 a template type argument, in which case the cv-qualifiers are
 ignored".
Adjust the example following to reflect this.

nathan


--
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
---
[ 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://www.research.att.com/~austern/csc/faq.html                ]