Topic: Const return value from functions


Author: jimad@microsoft.com (Jim Adcock)
Date: 07 Jul 92 17:43:54 GMT
Raw View
In article <1992Jul3.150836.14628@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
|In the absence of an exception (e.g. array type expression always
|converted to pointer) a simple positive indication of an expression's type
|is all that you'll ever find.

Huh?  Are you saying that array type expressions are always converted to
pointer?  If so, not true.




Author: jimad@microsoft.com (Jim Adcock)
Date: 07 Jul 92 17:25:31 GMT
Raw View
In article <1992Jul1.175146.21947@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
| 2) Beacuse returning a value also implies copying, thus
|calling the copy constructor, the same considerations apply.

I disagree that "returning a value" implies copying.  On the contrary,
I believe it is "well established" that C/C++ functions do not return
by copy, but rather return by value.  Journal of C Language Translation
had an article on this some time ago where this question came up before
the ANSI-C standing committee for resolution.  Also ARM page 300 has
a discussion of how compilers can avoid the copy when they are "smart enough"
to avoid aliasing problems.




Author: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Date: Wed, 8 Jul 1992 13:59:18 GMT
Raw View
In article <3409@hpwala.wal.hp.com> pabloh@hpwala.wal.hp.com (Pablo Halpern ) writes:
>
>Does anybody think that that functions should be allowed to return
>non-const l-values?  I don't (except for references to l-values).
>Modifying a temporary is just too strange a thing to do deliberately,
>even though, I admit, there are a few situations where it might be
>helpful.

 I cant answer this question because I don't know what
an 'rvalue' or 'lvalue' is anymore. The concepts do not make
sense for arbitrary class objects. Please define these terms.
Then I might disagree with you :-)

 'Modifying' a temporary is not the issue. Applying
a non-const function to a temporary is the issue. Do you realise
that class assignments can be const? [They would not implement
assignments though!]

 The issue here is modifying an object refered to in a temporary
via an assignment (say) to a temporary 'handle' class.

 For example,

 string s;
 s(1,2) = "Hi";

is an appealing syntax, but it depends on the temporary substring
object returned by

 substring string::operator()(int,int);

If s is const we might try

 const substring string::operator()(int,int) const;

to prevent assignment. It is not clear whether this is legal,
that is, whether the distinction makes any difference.


>
>- Pablo
>
>------------------------------------------------------------------------
>Pablo Halpern             (617) 290-3542
>HP Waltham                pabloh@hpwarq.wal.hp.com
>
>I am self-employed, so my opinions *do* reflect those of my employer.
>However, they may not reflect the opinions of my client.
>------------------------------------------------------------------------


--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: pkt@lpi.liant.com (Scott Turner)
Date: Fri, 3 Jul 1992 15:08:36 GMT
Raw View
John (MAX) Skaller writes:
> >There's no doubt a return value can always be considered a temporary
> >that can be copied to another place.  But nothing in the ARM or in the
> >standards committee's working paper says that its type would change
> >from const-T to T.
>
>  Therefore nothing says it WONT change either!

It would be impractical for the standard to enumerate all of the non-exceptional
cases.  In the absence of an exception (e.g. array type expression always
converted to pointer) a simple positive indication of an expression's type
is all that you'll ever find.

A grammar is another example of this.  It indicates grammatically legal
programs, and says nothing explicit about what's grammatically illegal.
One doesn't conclude that
 } {
might not be an illegal program.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: gjditchf@plg.waterloo.edu (Glen Ditchfield)
Date: Fri, 3 Jul 1992 14:44:15 GMT
Raw View
In article <1992Jul1.145013.11294@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>... const return values are a feature of ISO/ANSI C, and are a feature
>which cause negligible trouble to the programmer. ...  The proposal to
>ignore 'const' in the function return type would make explicit what is
>implicit in the C standard.

This isn't quite right.  The ANSI C standard says that "if the
specification of a function type includes any type qualifiers, the behavior
is undefined" (s. 3.5.3 "Type Qualifiers", p. 65).  A compiler can ignore
the 'const', or print a warning and discard it, or produce an a.out that
runs zork, or ...






Author: dpg@extro.ucc.su.OZ.AU (D P Gilbert)
Date: Fri, 3 Jul 1992 11:20:02 GMT
Raw View
bs@alice.att.com (Bjarne Stroustrup) writes:



>gjb@fig.citib.com (Greg Brail @ Citibank IBISM) writes

> > If const return types are legal, they had better be part of the ANSI
> > specification.

> I see no restrictions of what types can be used as return values.
> `const char *' is a type
>therefore
> `const char * f() { return "asdf"; }' is a legal function.

>The general point I'm trying to make is that a manual cannot ennumerate every
>legal combination. In the absense of an explicit restriction a combination
>must be assumed legal.

I'd just like to add my frustations at having useless and redundant "const"s
appearing in (member) function signatures. For example:

1) void foo(const char * const str);

2) void foo (char const * const str);

3) void foo(const String & const s);

4) class Fred { static int foo() const; };

5) Fred const & const foo(String const & const s);

Even though the 2nd "const"s in 1) and 2) are a (relatively pointless)
restriction on the implementor of foo(), they are still part of the
public signature of foo(). The placement of the 1st "const" in 2) is
confusing for the human reader (IMHO) but seemingly acceptable to the ARM,
cfront 2.0 and 2.1 . The usage of the 2nd "const" in 3) is meaningless
but accepted (without warning) by cfront 2.0 and 2.1 (at least it
doesn't appear in the function's signature - at least according to the
name mangling algorithm). Thankfully the "const" in 4) is flagged as
an error in cfront 2.1 (2.0 accepted it, without even a warning I think).
Example 5) is "const" gone mad (and it's been seen in production code).

The scope for useless, redundant, and confusing type modifiers in C (and
hence C++) is evident. I agree that banning such silliness is not
practical. Perhaps the "standard" could suggest to compiler writers that
all (most) ignored type modifiers generate a warning.

Doug Gilbert





Author: checker@acf3.nyu.edu (Christopher Hecker)
Date: Fri, 3 Jul 1992 20:02:03 GMT
Raw View
>1) void foo(const char * const str);
>2) void foo (char const * const str);
>3) void foo(const String & const s);

>Even though the 2nd "const"s in 1) and 2) are a (relatively pointless)
>restriction on the implementor of foo(), they are still part of the
>public signature of foo().

While I think changing pass-by-value parameters in the function body is
usually bad style, I think allowing them to be const is a good thing.
It is useful for the same reason const variables that are auto are
useful.

>The placement of the 1st "const" in 2) is
>confusing for the human reader (IMHO) but seemingly acceptable to the ARM,
>cfront 2.0 and 2.1 .

I would disagree here.  I write my consts this way, and find it is more
consistent when you get up into complex declarations and typedefs.  I
don't want to start an rwar, but I can provide examples, if you'd like.

>The usage of the 2nd "const" in 3) is meaningless
>but accepted (without warning) by cfront 2.0 and 2.1 (at least it
>doesn't appear in the function's signature - at least according to the
>name mangling algorithm).

I would say that anyone who writes the 2nd const doesn't understand
references well enough to be using them in production code.

All of that said, though, my rule of thumb is, Make it const unless you
absolutely can't.


Chris





Author: pkt@lpi.liant.com (Scott Turner)
Date: Sun, 5 Jul 1992 03:31:28 GMT
Raw View
Glen Ditchfield writes:
> In article <1992Jul1.145013.11294@lpi.liant.com> pkt@lpi.liant.com (Scott Turner
> ) writes:
> >... const return values are a feature of ISO/ANSI C, and are a feature
> >which cause negligible trouble to the programmer. ...  The proposal to
> >ignore 'const' in the function return type would make explicit what is
> >implicit in the C standard.
>
> This isn't quite right.  The ANSI C standard says that "if the
> specification of a function type includes any type qualifiers, the behavior
> is undefined" (s. 3.5.3 "Type Qualifiers", p. 65).  A compiler can ignore
> the 'const', or print a warning and discard it, or produce an a.out that
> runs zork, or ...

What that sentence from 3.5.3 is dealing with is qualified function
type, not qualified return type of a function.  The behavior of
 typedef int T;
 typedef T F();
 extern const F f; // const function type
is undefined in the C standard.  On the other hand,
 typedef int T;
 typedef const T F(); // function returns const type
 extern F f;
is legal and behaves just as if the 'const' were not there.
It's the latter which we're discussing.  It leads to a question
in C++ because a function call expression can be the object
of a member function call.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI language products)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: ...uunet!lpi!pkt          Internet: pkt@lpi.liant.com




Author: pkt@lpi.liant.com (Scott Turner)
Date: Mon, 22 Jun 1992 13:57:26 GMT
Raw View
John (Max) Skaller writes (in comp.lang.c++):
> What is the meaning if any of a const return type?
> ...
> const T y();
> ...
> y() = T();

That's an interesting example.  I've considered the ability to specify
a return type 'const' a useless anomaly, but in this case it could
make a difference.  There's a proposal before the C++ standards
committee that 'const' at the top level of a return type be ignored.
However, the 4 compilers I tried (cfront2.1, cfront3.0, LPI, Oregon)
all paid attention to 'const' in the following.
 struct S {
     S();
     S (const S&);
     void mf ();
 };
 extern S is();
 extern const S cis();
 void foo() {
    is().mf(); // OK
    cis().mf(); // error
 }

Your reasoning supports the idea that the latter call to 'mf' is no
worse than the former.  I'm led to wonder whether either should be
permitted.  To call a non-const member function for such a temporary
is analogous to passing the temporary to a non-const reference, which
was made illegal when the ARM came out.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Date: Wed, 24 Jun 1992 18:01:59 GMT
Raw View
In article <1992Jun22.135726.2886@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>John (Max) Skaller writes (in comp.lang.c++):
>> What is the meaning if any of a const return type?
>> ...
>> const T y();
>> ...
>> y() = T();
>
>That's an interesting example.  I've considered the ability to specify
>a return type 'const' a useless anomaly, but in this case it could
>make a difference.  There's a proposal before the C++ standards
>committee that 'const' at the top level of a return type be ignored.
>However, the 4 compilers I tried (cfront2.1, cfront3.0, LPI, Oregon)
>all paid attention to 'const' in the following.
> struct S {
>     S();
>     S (const S&);
>     void mf ();
> };
> extern S is();
> extern const S cis();
> void foo() {
>    is().mf(); // OK
>    cis().mf(); // error
> }
>
>Your reasoning supports the idea that the latter call to 'mf' is no
>worse than the former.  I'm led to wonder whether either should be
>permitted.  To call a non-const member function for such a temporary
>is analogous to passing the temporary to a non-const reference, which
>was made illegal when the ARM came out.

 Mm. [Deleted first reply ... ]

 Your argument seems more convincing the more I think about
it, but it would break LOTS of code, make smart pointers useless
as lvalues, etc.

 That code relys on mods to a temporary having non-temporary
side effects. Why would one ever want to modify a temporary
which did not cause side effects? For efficiency?

 f(const list&);
 f( i()+=k ); // ?? (append list k to i efficiently)

[The issue is the constness of i(), not the param of f.]


--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: gjb@fig.citib.com (Greg Brail)
Date: Fri, 26 Jun 1992 22:20:10 GMT
Raw View
In article <1992Jun22.135726.2886@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>John (Max) Skaller writes (in comp.lang.c++):
>> What is the meaning if any of a const return type?
>> ...
>> const T y();
>> ...
>> y() = T();
>
>That's an interesting example.  I've considered the ability to specify
>a return type 'const' a useless anomaly, but in this case it could
>make a difference.  There's a proposal before the C++ standards
>committee that 'const' at the top level of a return type be ignored.

What about:

class B
{
public:
    B();
    void Change();
    operator const char*() const;
};

class A
{
public:
    A();
    const B& GetB() const
    { return b; }
private:
    B b;
};

Let's say the implementor of class A wants to make sure people can get
a B object. For instance, let's say B is some form of string class.
Users of class A might want to be able to write:

A a;
cout << a.GetB();

But the writer of class A doesn't want users to write:

A a;
a.GetB().Change();

(And the Sun 2.1 C++ compiler with the +p option won't allow this.)

Furthermore, whomever wrote class A would rather allocate the storage
for the B object at creation time than allocate a new B every time
someone calls GetB.

In this case, it seems to me that const return types are useful. Of course,
this all assumes that calling A::GetB() results in the return of some
sort of "real" reference instead of the creation of a temporary.
If calling GetB() results in a temporary, then perhaps all bets are off.

Does any of this make sense, or are const return types as useless as
everyone else thinks? Is the fictional implementor of class A sane,
or not?

Don't know about you, but I find const return types very useful. I can
see no reason to legislate them out of existence via the standards committee.

    greg
--
Greg Brail   Citibank      gjb@fig.citib.com

"Undefined symbol! Your mother is an undefined symbol!"
 -- Someone I once worked for




Author: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Date: Sat, 27 Jun 1992 17:51:41 GMT
Raw View
In article <1992Jun26.222010.19745@fig.citib.com> gjb@fig.citib.com (Greg Brail) writes:
>In article <1992Jun22.135726.2886@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>>John (Max) Skaller writes (in comp.lang.c++):
>>> What is the meaning if any of a const return type?
>>> ...
>>> const T y();
>>> ...
>>> y() = T();
>>
>>That's an interesting example.  I've considered the ability to specify
>>a return type 'const' a useless anomaly, but in this case it could
>>make a difference.  There's a proposal before the C++ standards
>>committee that 'const' at the top level of a return type be ignored.
>

[description of usefulness of const return types deleted]

>
>In this case, it seems to me that const return types are useful. Of course,
>this all assumes that calling A::GetB() results in the return of some
>sort of "real" reference instead of the creation of a temporary.
>If calling GetB() results in a temporary, then perhaps all bets are off.

 Thats the point. I am not asking "how would you use
a const return type?" I wanted to use it just as you describe!

 The problem is:
 a) My compiler doesn't recogize it

 b) Cannot a return value ALWAYS be considered a temporary,
 that is then copied to another place (loosing its constness).

 c) Functions f(int) and f(const int) cannot be distinguisjed
 because the rule in the ARM is that their initialisers
 must be distinguishable. Cannot the same argument
 be applied to return values?

 d) The fact that ANSI considers it problematical is indicative
 of the problems.

WHAT is the position at the moment? I my compiler broken, or is
the language definition imprecise here?

We need to know because even simple classes like 'string' might
rely on a non-standard feature.

It is too hard for me to work out
 a) what the ARM says
 b) what it *should* say
because I am not smart enough, and also
 c) what ANSI says
because I don't have access to ANSI.

HELP!
>
>Does any of this make sense, or are const return types as useless as
>everyone else thinks? Is the fictional implementor of class A sane,
>or not?
>
>Don't know about you, but I find const return types very useful. I can
>see no reason to legislate them out of existence via the standards committee.

 I can't see a *definite* reason. But I can't prove that
const return values are well defined. ANSI would not be legislating
them out of existence, it would be removing a discrimination
with a non-const return value if the rest of the language were
defined in such a way that you could not reliable expect to
actually GET a const value when you wanted one.

In this case "implementation dependent" is NOT acceptable.
If it is implementation dependent, it is in effect, illegal.

[Most other implementation dependencies are either hidable
in the data parts (like sizes of int) or are things
you wouldn't want to do anyhow. In this case you
WANT to discriminate if it is standard, and had better
not if it isn't]

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: pkt@lpi.liant.com (Scott Turner)
Date: Sun, 28 Jun 1992 02:23:57 GMT
Raw View
I gave a reason why calling a non-const member function for a
temporary might be considered illegal.

John (MAX) Skaller writes:
>  Your argument seems more convincing the more I think about
> it, but it would break LOTS of code, make smart pointers useless
> as lvalues, etc.
>
>  That code relys on mods to a temporary having non-temporary
> side effects. Why would one ever want to modify a temporary
> which did not cause side effects? For efficiency?
>
>  f(const list&);
>  f( i()+=k ); // ?? (append list k to i efficiently)
>
> [The issue is the constness of i(), not the param of f.]

Another intriguing example.  Both this and the common idiom of smart
pointers have in common a member function (operator += or operator->)
returning a reference or pointer to *this.  In doing so, they may run
afoul of temporaries being destroyed before the program is done with
them (see section 12.2 of the C++ Reference Manual).  The standards
committee is leaning towards changing the rules for temporaries, so
that idioms like these will work.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: pkt@lpi.liant.com (Scott Turner)
Date: Tue, 30 Jun 1992 13:48:45 GMT
Raw View
I wrote:
> There's a proposal before the C++ standards
> committee that 'const' at the top level of a return type be ignored.

Greg Brail writes:
> What about:
>
> class B
> {
> public:
>     B();
>     void Change();
>     operator const char*() const;
> };
>
> class A
> {
> public:
>     A();
>     const B& GetB() const
>     { return b; }
> private:
>     B b;
> };
>
> Let's say the implementor of class A wants to make sure people can get
> a B object. For instance, let's say B is some form of string class.
> Users of class A might want to be able to write:
>
> A a;
> cout << a.GetB();
>
> But the writer of class A doesn't want users to write:
>
> A a;
> a.GetB().Change();
>
> (And the Sun 2.1 C++ compiler with the +p option won't allow this.)
>
> Furthermore, whomever wrote class A would rather allocate the storage
> for the B object at creation time than allocate a new B every time
> someone calls GetB.
>
> In this case, it seems to me that const return types are useful.

Your example is not a const return type in the sense John (MAX) Skaller
brought up the question.  It is a reference to const, so 'const' is
not at the top level of the return type.  There is no
question of how 'const' affects returns when it's a matter of
returning reference-to-const-B versus returning reference-to-B.

> Of course,
> this all assumes that calling A::GetB() results in the return of some
> sort of "real" reference instead of the creation of a temporary.
> If calling GetB() results in a temporary, then perhaps all bets are off.

No need for anxiety on this point either.  In your example no temporary
will be created.  Also, no decent compiler will create a temporary when
returning a reference, without at least warning about it.

> Does any of this make sense, or are const return types as useless as
> everyone else thinks? Is the fictional implementor of class A sane,
> or not?

Many sane people have created classes which work as A does.

> Don't know about you, but I find const return types very useful. I can
> see no reason to legislate them out of existence via the standards committee.

There are a fair number of users in the C++ standards committee, and
the implementers generally value their perspective.  A proposal
to outlaw a commonly used feature would not get anywhere.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI language products)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: ...uunet!lpi!pkt          Internet: pkt@lpi.liant.com




Author: gjb@fig.citib.com (Greg Brail)
Date: Tue, 30 Jun 1992 05:15:35 GMT
Raw View
In article <1992Jun27.175141.26585@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
>WHAT is the position at the moment? I my compiler broken, or is
>the language definition imprecise here?
>
>We need to know because even simple classes like 'string' might
>rely on a non-standard feature.
>...
>[Most other implementation dependencies are either hidable
>in the data parts (like sizes of int) or are things
>you wouldn't want to do anyhow. In this case you
>WANT to discriminate if it is standard, and had better
>not if it isn't]

I wasn't trying to demonstrate how to use a const return type. I saw someone
calling them a "useless anamoly," and wanted to show they aren't useless.

Sadly, they seem to be an anamoly. So I second Mr. Skaller's request. If
const return types are legal, they had better be part of the ANSI
specification. If they're useless, then the ANSI committee ought to make them
illegal. Making them "implementation-defined" just makes them dangerous.
Personally, I hope they'll be legal.

    greg
--
Greg Brail   Citibank      gjb@fig.citib.com

"Undefined symbol! Your mother is an undefined symbol!"
 -- Someone I once worked for, to her compiler




Author: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Date: 30 Jun 92 18:53:00 GMT
Raw View
In article <1992Jun30.134845.801@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>I wrote:
>> There's a proposal before the C++ standards
>> committee that 'const' at the top level of a return type be ignored.
>
>> Does any of this make sense, or are const return types as useless as
>> everyone else thinks? Is the fictional implementor of class A sane,
>> or not?
>
>Many sane people have created classes which work as A does.
>
>> Don't know about you, but I find const return types very useful. I can
>> see no reason to legislate them out of existence via the standards committee.
>
>There are a fair number of users in the C++ standards committee, and
>the implementers generally value their perspective.  A proposal
>to outlaw a commonly used feature would not get anywhere.
>--

 If that feature were INCONSISTENT it had BETTER be outlawed.

 I also would like to have const return types.
 If they made sense, I could use them.

 It is not a question of whether you want them or not,
the question is: do they make sense in the greater
context of the language.

 In particular, f(int) and f(const int) CANNOT be distinguished.
[They have the same initialisers, the same copy contructor is invoked
to copy the argument of the caller to the parameter of the routine]

 In the context of call by value requiring copy contructors,
it should be legal to write

 class X { void f(int); } // ought to allow integer expression
 X::f(const int i){ ... } // just prevents f changing i
   // implementation detail only
   // refers to local copy

Of course the distinction between whether the 'const' refers
to the argument or parameter cannot be made. [There is
no syntax for it]

And the distinction is useful where inlining is used, and
also where a different call method might be used
(pass reference to const instead of value if it's const)

Anyhow, what I want to know is: does a const return type
make sense? If not, why not? Can the language be fixed
to allow it to make sense? If not it had better be made
an error, IMHO (or at least a warning).

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------




Author: pkt@lpi.liant.com (Scott Turner)
Date: Wed, 1 Jul 1992 14:50:13 GMT
Raw View
John (MAX) Skaller writes:
> const T y();
> ...
> y() = T();
and writes more:
>  Thats the point. I am not asking "how would you use
> a const return type?" I wanted to use it just as you describe!

Skaller's example differs from Brail's.  The above falls into a muddy
area of C++ because the function returns const-T rather than
reference-to-const-T.

>  The problem is:
>  a) My compiler doesn't recogize it
>
>  b) Cannot a return value ALWAYS be considered a temporary,
>  that is then copied to another place (loosing its constness).

There's no doubt a return value can always be considered a temporary
that can be copied to another place.  But nothing in the ARM or in the
standards committee's working paper says that its type would change
from const-T to T.

One committee member has submitted a written proposal to deal with
several nits in the working paper's type system.  It is suggested to
eliminate the distinction between function returning const T and
function returning T.  A qualifier such as 'const' in the function
return type would be ignored.

>  c) Functions f(int) and f(const int) cannot be distinguished
>  because the rule in the ARM is that their initialisers
>  must be distinguishable. Cannot the same argument
>  be applied to return values?

The reasoning you cite is based on hypothetically determining which
overloaded version of "f" to call.  Overloading is irrelevant to
return values.  A related argument could be attempted with return
values, but it would beg the question.

>  d) The fact that ANSI considers it problematical is indicative
>  of the problems.
>
> WHAT is the position at the moment? I my compiler broken, or is
> the language definition imprecise here?
> ...
> It is too hard for me to work out
>  a) what the ARM says

In addition to the gray area mentioned above, the ARM is not explicit
regarding the temporary object which is bound to 'this' when a member
function is called for a non-lvalue.

>  c) what ANSI says
> because I don't have access to ANSI.

Unfortunately, it still says the same as the ARM.  It takes time to
come up with a standard.  Even if the working paper gave an answer to
your issue, I would have to include a reminder that it's not an ANSI
or ISO standard yet, and is subject to change.

At this point, widely used implementations such as AT&T cfront provide
a de facto standard.  It's not often worth arguing with them even if
they contradict the ARM.

> Anyhow, what I want to know is: does a const return type
> make sense? If not, why not?

IMO a const return type does not make sense.  The reason is that
qualifiers only make sense in the context of an lvalue, a reference to
qualified type, or a pointer to qualified type.  A call to a function
returning a const type is not any of these.  But opinion and such
reason matter little, because const return values are a feature of
ISO/ANSI C, and are a feature which cause negligible trouble to the
programmer.

> Can the language be fixed
> to allow it to make sense? If not it had better be made
> an error, IMHO (or at least a warning).

The proposal to ignore 'const' in the function return type would make
explicit what is implicit in the C standard.  I think it's the right
answer to this issue.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com






Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 1 Jul 92 17:18:20 GMT
Raw View

gjb@fig.citib.com (Greg Brail @ Citibank IBISM) writes

 > If const return types are legal, they had better be part of the ANSI
 > specification.

 I see no restrictions of what types can be used as return values.
 `const char *' is a type
therefore
 `const char * f() { return "asdf"; }' is a legal function.

The general point I'm trying to make is that a manual cannot ennumerate every
legal combination. In the absense of an explicit restriction a combination
must be assumed legal.





Author: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Date: Wed, 1 Jul 1992 17:51:46 GMT
Raw View
In article <1992Jul1.145013.11294@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
>John (MAX) Skaller writes:
>> const T y();
>> ...
>> y() = T();
>and writes more:
>>  Thats the point. I am not asking "how would you use
>> a const return type?" I wanted to use it just as you describe!
>
>Skaller's example differs from Brail's.  The above falls into a muddy
>area of C++ because the function returns const-T rather than
>reference-to-const-T.
>
>>  The problem is:
>>  a) My compiler doesn't recogize it
>>
>>  b) Cannot a return value ALWAYS be considered a temporary,
>>  that is then copied to another place (loosing its constness).
>
>There's no doubt a return value can always be considered a temporary
>that can be copied to another place.  But nothing in the ARM or in the
>standards committee's working paper says that its type would change
>from const-T to T.

 Therefore nothing says it WONT change either!
>
>One committee member has submitted a written proposal to deal with
>several nits in the working paper's type system.  It is suggested to
>eliminate the distinction between function returning const T and
>function returning T.  A qualifier such as 'const' in the function
>return type would be ignored.
>
>>  c) Functions f(int) and f(const int) cannot be distinguished
>>  because the rule in the ARM is that their initialisers
>>  must be distinguishable. Cannot the same argument
>>  be applied to return values?
>
>The reasoning you cite is based on hypothetically determining which
>overloaded version of "f" to call.  Overloading is irrelevant to
>return values.  A related argument could be attempted with return
>values, but it would beg the question.

 I'm not quite convinced.

 Below is an argument (not necessarily one I believe ..)

 1) f(int) and f(const int) cannot be distinguished because
with call by value you (might) invoke the copy constructor to copy the argument
to the parameter. Since the 'this' object of the constructor cannot
be labelled const or the const omitted, it follows the 'const' in
value parameters is ALSO meaningless.

 [It really is meaningless in the declaration. the const
has meaning only in the definition. I should be able to do this:

 f(int); // declaration

 f(const int x) { ..} // definition

The const here prevents the definition changing the parameter,
because of call by value that has nothing to do with changing the argument.

 The reverse applies:

 f(const int);

 f(int x) { x++; };

ought to be legal.

In other words, const arguments are meaningless.
]

 2) Beacuse returning a value also implies copying, thus
calling the copy constructor, the same considerations apply.

>
>>  d) The fact that ANSI considers it problematical is indicative
>>  of the problems.
>>
>> WHAT is the position at the moment? I my compiler broken, or is
>> the language definition imprecise here?
>> ...
>> It is too hard for me to work out
>>  a) what the ARM says
>
>In addition to the gray area mentioned above, the ARM is not explicit
>regarding the temporary object which is bound to 'this' when a member
>function is called for a non-lvalue.
>
>>  c) what ANSI says
>> because I don't have access to ANSI.
>
>Unfortunately, it still says the same as the ARM.  It takes time to
>come up with a standard.

 No complaint about the time. Just that until you said the above
I did not know and could not find out.

>Even if the working paper gave an answer to
>your issue, I would have to include a reminder that it's not an ANSI
>or ISO standard yet, and is subject to change.
>
>At this point, widely used implementations such as AT&T cfront provide
>a de facto standard.  It's not often worth arguing with them even if
>they contradict the ARM.
>
>> Anyhow, what I want to know is: does a const return type
>> make sense? If not, why not?
>
>IMO a const return type does not make sense.  The reason is that
>qualifiers only make sense in the context of an lvalue, a reference to
>qualified type, or a pointer to qualified type.  A call to a function
>returning a const type is not any of these.  But opinion and such
>reason matter little, because const return values are a feature of
>ISO/ANSI C, and are a feature which cause negligible trouble to the
>programmer.
>
>> Can the language be fixed
>> to allow it to make sense? If not it had better be made
>> an error, IMHO (or at least a warning).
>
>The proposal to ignore 'const' in the function return type would make
>explicit what is implicit in the C standard.  I think it's the right
>answer to this issue.

 Arguments about 'lvalue' and 'rvalue' are a little problematical.
For standard types, OK. But for a class you can define the assignment
operator so that it does not require an lvalue on the left. Indeed,
any member.

 BUT there is good reason to distinguish const and non-const
objects then, we want the assignment to be a syntax error!

 The problem arises with handle classes.

 In particular a very common technique for String is to have
a class Substring also, the notation

 s(2,4)

creates a Substring VALUE to which one can assign another string,
the operator= then copies the string into the right place in 's'.
[we define Substring String::operator()(int,int)]

 s(2,4)="Fred";

Here it is crucial to distinguish between const and non-const
objects: if 's' were a const variable, the assignment should
be illegal, to make it illegal DEPENDS on the Substring object

 s(2,4)

also being const. If const and non const return types are
indistinguishable, this technique cannot work, and
almost every existing String class and Handle class is
broken.

Perhaps they are already broken.

BEFORE I publish my string class I want to know if I am using
a 'naughty' technique.
>--
>Prescott K. Turner, Jr.
>Liant Software Corp. (developers of LPI languages)
>959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
>UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com
>
>


--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------