Topic: constant


Author: ccg@freemail.c3.hu (Andras Erdei)
Date: 1999/04/21
Raw View

>Well, even if it does, it is a *temporary* lvalue.  Thus assigning to the
>return value almost always immediately throws away the result!  This is the
>reason one doesn't usually want to do that.

The problem is not with op=() -- it is just the most trivial
example. Returning a const from a function restricts the
caller to use only the const member fns; so IMHO returning
a const is a good habit (the same stands for const references).
It is rare when u want to allow the caller to invoke non-const
members (and seeing something like ++f() is usually confusing).

struct A
{
...
B const foo( C const * const ) const ;
}

the four consts have four meanings:

  4th: foo() can be invoked for const As

  3rd: the value of the pointer will not be changed by foo() so
         the *compiler* can do some optimizations based on this
         fact (e.g. if the pointer is passed in a register then
         after returning from foo() it can still be used)
  note that the (human) user of foo() gets no information from
  this 'const' -- it is about how foo() was implemented

  2nd: contrary to the 3rd, this is for the *caller* of foo():
           it promises that foo() will invoke only const members
           (which in most cases means that will not change the
           pointed value)
  note that foo() can still delete the pointed object

  1st: it restricts the usage of the result given by foo()

  Erdei Andras
  ccg@freemail.c3.hu



[ 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.Kanze@dresdner-bank.com
Date: 1999/04/13
Raw View
In article <7es9fu$6ja@news3.euro.net>,
  "Martijn Lievaart" <nobody@orion.nl> wrote:

> I think you are wrong. A function returning a scalar returns an lvalue (not
> sure about a function returning an UDT, anyone can tell what the rules here
> are?).

I think you mean rvalue.  The rule is simple: if the return type is a
reference, the expression is an lvalue, otherwise, it is an rvalue.
(Any expression which has reference type is an rvalue.)

> I think you are confused with references, where it does matter.
>
> For instance MSVC says the following, I think it is right.
>
> int f()
> {
>  return 0;
> }
>
> void g()
> {
>  f() = 42;
> }
>
> C:\projects\testje\constreturn\main.cpp(10) : error C2106: '=' : left
> operand must be l-value

Correct.  The difference is only apparent for types with a user defined
operator=.  For example:

    struct T { T& operator=( T const& other ) {} } ;

    T f()
    {
        return T() ;
    }

    T const g()
    {
        return T() ;
    }

    void test()
    {
        f() = T() ;             //  legal
        g() = T() ;             //  illegal -- because of a violation
                                //  of const, though, and not an lvalue
                                //  violation
    }

As far as I know, Scott Meyers was the first to recognize that const
return values could be used to simulate rvalue-ness.  (At least, I
learned it from him.)

--
James Kanze                         mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                        Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany  Tel. +49 (069) 63 19 86 27

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: 1999/04/14
Raw View
Gabriel Dos_Reis wrote:
>
> James Kuyper <kuyper@wizard.net> writes:
>
> | Gabriel Dos_Reis wrote:
> | >
> | > James.Kanze@dresdner-bank.com writes:
> | >
> | > [...]
> | >
> | > | Correct.  The difference is only apparent for types with a user defined
> | > | operator=.  For example:
> | > |
> | > |     struct T { T& operator=( T const& other ) {} } ;
> | >                                                ^^^^
> | > undefined behaviour.
> |
> | It's not undefined, it's empty.
>
> Oh well, 6.6.3/2 says:
>
> ---
>         ... Flowing off the end of a function is equivalent to a
>         return with no value; this results in undefined behaviour in a
>         value-returning function.
> ---
>
> Unless I'm mistaken, T::operator= is declared to return a T& and
> actually does return nothing--since its' definition is empty. What am
> I missing?

Nothing. Sorry, this is just another case where I missed the 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: stanley@west.sun.com (Stanley Friesen [Contractor])
Date: 1999/04/15
Raw View
In article <3713D3E8.1ADFE373@wizard.net>,
James Kuyper  <kuyper@wizard.net> wrote:
>For a user defined type, operator=() might be defined to do almost
>anything, including having side-effects that will continue after the
>temporary has been discarded.

Yes, that is so.  In general, I would consider such behavior to be a
questionable design though.

[Even overloading >> and << as I/O operators was somewhat less than
optimal].
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/13
Raw View
James.Kanze@dresdner-bank.com writes:

[...]

| Correct.  The difference is only apparent for types with a user defined
| operator=.  For example:
|
|     struct T { T& operator=( T const& other ) {} } ;
                                               ^^^^
undefined behaviour.

I would simply have written:

 struct T {};

--
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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: stanley@west.sun.com (Stanley Friesen [Contractor])
Date: 1999/04/13
Raw View
In article <7es9fu$6ja@news3.euro.net>,
Martijn Lievaart <nobody@orion.nl> wrote:
>>    function1() = 2 + 2;
>>
>>Usually you don't want to do that. When you do want to do that, you're
>>probably returning a reference (rather than a copy, as in this example).
>>
>
>I think you are wrong. A function returning a scalar returns an lvalue (not
>sure about a function returning an UDT, anyone can tell what the rules here
>are?).

Well, even if it does, it is a *temporary* lvalue.  Thus assigning to the
return value almost always immediately throws away the result!  This is the
reason one doesn't usually want to do that.

As stated, this *may* be meaningful if the return value is a reference *and*
it is a reference to some object with non-temporary lifetime (such as, say,
something stored in a container - e.g. the value returned by operator[]
in std::vector).
---
[ 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: 1999/04/13
Raw View
Gabriel Dos_Reis wrote:
>
> James.Kanze@dresdner-bank.com writes:
>
> [...]
>
> | Correct.  The difference is only apparent for types with a user defined
> | operator=.  For example:
> |
> |     struct T { T& operator=( T const& other ) {} } ;
>                                                ^^^^
> undefined behaviour.

It's not undefined, it's empty.
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/14
Raw View
James Kuyper <kuyper@wizard.net> writes:

| Gabriel Dos_Reis wrote:
| >
| > James.Kanze@dresdner-bank.com writes:
| >
| > [...]
| >
| > | Correct.  The difference is only apparent for types with a user defined
| > | operator=.  For example:
| > |
| > |     struct T { T& operator=( T const& other ) {} } ;
| >                                                ^^^^
| > undefined behaviour.
|
| It's not undefined, it's empty.

Oh well, 6.6.3/2 says:

---
 ... Flowing off the end of a function is equivalent to a
 return with no value; this results in undefined behaviour in a
 value-returning function.
---

Unless I'm mistaken, T::operator= is declared to return a T& and
actually does return nothing--since its' definition is empty. What am
I missing?

--
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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1999/04/14
Raw View
Stanley Friesen [Contractor] wrote:
....
> Well, even if it does, it is a *temporary* lvalue.  Thus assigning to the
> return value almost always immediately throws away the result!  This is the
> reason one doesn't usually want to do that.
>
> As stated, this *may* be meaningful if the return value is a reference *and*
> it is a reference to some object with non-temporary lifetime (such as, say,
> something stored in a container - e.g. the value returned by operator[]
> in std::vector).

For a user defined type, operator=() might be defined to do almost
anything, including having side-effects that will continue after the
temporary has been discarded.
---
[ 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: "Martijn Lievaart" <nobody@orion.nl>
Date: 1999/04/13
Raw View
[ comp.std.c++ added to the newsgroups, I think the guru's over there can
say a lot more on the subject... Martijn ]

Braden N. McDaniel wrote in message <923621512.959.11@news.remarQ.com>...
>Pete Grant <grantpk@email.msn.com> wrote in message
>news:Okb2HKbg#GA.228@upnetnews05...
>> >pradeepj@delhi.tcs.co.in wrote in message
>> ><7ehv4r$v81$1@nnrp1.dejanews.com>...
>> >>Hi!
>> >>If somebody says a function returns constant then what does it mean.
>> >>
>> >>e.g.
>> >>
>> >>const int function1()
>> >>
>>
>> RA Scheltema <scheltem@kpn.research.com> wrote in message
>> news:370c887d.0@pandora.research.kpn.com...
>> >This means that the variable it returns is constant. This implies that
>you
>> >cannot change it.
>> >
>> >Example:
>> >const int i = function1();
>> >i=9; // This action now is forbidden.
>> >
>>
>> Not quite -- although the example shown is correct because i is declared
>as
>> const.
>>
>> In the case of functions returning objects, the const declaration is
>> meaningless.  For example:
>>
>>   const int function1();
>>   int n = function1();  // legal even though the function supposedly
>returns
>> const
>>   n = 5;  // legal
>>
>> If the function returned a reference or a pointer to an object, then
const
>> would have real meaning.
>
>It is not meaningless. If the function did not return a const value, it
>would be legal to do something like this:
>
>    function1() = 2 + 2;
>
>Usually you don't want to do that. When you do want to do that, you're
>probably returning a reference (rather than a copy, as in this example).
>

I think you are wrong. A function returning a scalar returns an lvalue (not
sure about a function returning an UDT, anyone can tell what the rules here
are?).

I think you are confused with references, where it does matter.

For instance MSVC says the following, I think it is right.

int f()
{
 return 0;
}

void g()
{
 f() = 42;
}

C:\projects\testje\constreturn\main.cpp(10) : error C2106: '=' : left
operand must be l-value

Martijn
--
My reply-to address is intentionally set to /dev/null
reply to mlievaart at orion in nl
---
[ 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              ]