Topic: Return Value and Function's Signature.


Author: dak <pierreba@poster.cae.ca>
Date: 1996/10/25
Raw View
Igor Boukanov (boukanov@sentef2.fi.uib.no) wrote:
> Andreas Schwab (schwab@issan.informatik.uni-dortmund.de) wrote:
> > And which function should be called here:
> >  (void)foo();
> > or here:
> >  float x = foo();
> > when SomeClass has operator float()?
>
> None. A compiler should produce an error in any case when there are the result
> overloading and more than one implicit conversion to choose.
> The same should take place for the call:
> (void)foo();
>
> And in this case (type)foo() should not mean cast operator, it just suggest
> which function to select.

One way to embed your suggestion in the syntax without breaking programs
and changing the meaning of casting would be to reuse the new explicit
keyword. Simply define the functions which can be overloaded by return type
as explicit.  [Example:

class A
{
  explicit int foo ();
  explicit float foo ();
};

--end example]

Then calling the function with the wrong type to receive the return value
would be an error (err... I mean would require a diagnostic). The only
way to call the function would be either as part of an expression were the
type expected is known (for example a function in a function call) or with
a variable. A dummy variable could be used in the case only the side-effects
are desired. The compiler could optimize-out the variable if it is a simple
type.

That would also fix the problem of choosing which conversion to implement
for a fixed-point class, because the type chosen would have to be explicitly
given.

The major problem with this proposal is that it would change the way the
signature of a function would be used, even how they are encoded for some
compilers. That may break link-compatibility. But since all compilers keep
the return type in the signature to verify declaration-usage correctness,
I doubt it would harm anything.

So another way to get overloading with return types would be to have a
verify_cast<> which would only verify the type being casted. By casting the
return type with it, you can select which function is called. Ambiguities
would be flagged and require a diagnostic.  [Example:

class A
{
 int foo ();
 float foo ();
};

void bar ()
{
 A a;
 int i = a.foo ();                   // Ok, calls int A::foo ()
 float f = a.foo ();                 // Ok, calls float A::foo ()
 double d = a.foo ();                // Error, which foo ?
 long l = verify_cast<int> a.foo (); // Ok, return type selected.
}

--end example]

It would also be useful to serve as guard in numeric computation so that
it is possible to verify the type in the middle of an expression so that
precision is known.  [Example:

// in header somewhere...

float a ();
float b ();

// much later...

void preciseFoo ()
{
 double d = a () * b (); // Am I computing doubles ?
 double d = verify_cast<double> ( a () ) * verify_cast<double> ( b () );
}

--end example]

dak@cae.ca
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1996/10/28
Raw View
Andreas Schwab wrote:
>
> Igor Boukanov <boukanov@sentef1.fi.uib.no> writes:
>
> |> Chung-chieh Shan (ccshan@husc.harvard.edu) wrote:
> |>> Because there's no way to distinguish between the following calls:
>
> |>> >   int foo();
> |>> foo();
>
> |>> > and
> |>> and
>
> |>> >   SomeClass& foo();
> |>> foo();
>
> |> These contradictions can always be resolved via
> |>     (int)foo();
> |>     (SomeClass&)foo();
>
> |> So u need another argumentation to reject the result overloading.
>
> And which function should be called here:
>
>         (void)foo();

The conversions
- from int to void
- from SomeClass& to void
are equivalents, one is not better than the other (at least I think)

So the call is ambigous.

> or here:
>
>         float x = foo();
>
> when SomeClass has operator float()?

int foo () is called since it only involve perdefined conversions, not
user defined

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ccshan@husc.harvard.edu (Chung-chieh Shan)
Date: 1996/10/21
Raw View
Daniel Pflager (dpflag@ix.netcom.com) wrote:
> I wonder if anyone knows what the semantic constraint might be that decided
> the return value would not participate in operator overload resolution.

Because there's no way to distinguish between the following calls:

>  int foo();
    foo();

> and
and

>  SomeClass& foo();
    foo();

[ mod note: See also the discussions in the ARM and in D&E -sdc ]

--
blue | Ken; Shan, Chung-chieh; Sian7, Tiong1-kiat8; ccshan@fas.harvard.edu.
 ()  | Your code today becomes the mind tomorrow:  Your plan its means,
 /\  | your dream its ends, your ideal its elegance.  Hack on.


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: boukanov@sentef1.fi.uib.no (Igor Boukanov)
Date: 1996/10/22
Raw View
Chung-chieh Shan (ccshan@husc.harvard.edu) wrote:
> Because there's no way to distinguish between the following calls:

> >  int foo();
>     foo();

> > and
> and

> >  SomeClass& foo();
>     foo();

These contradictions can always be resolved via
    (int)foo();
    (SomeClass&)foo();

So u need another argumentation to reject the result overloading.

[ mod note: see the discussion in the ARM and in D&E. -sdc ]
--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: schwab@issan.informatik.uni-dortmund.de (Andreas Schwab)
Date: 1996/10/23
Raw View
Igor Boukanov <boukanov@sentef1.fi.uib.no> writes:

|> Chung-chieh Shan (ccshan@husc.harvard.edu) wrote:
|>> Because there's no way to distinguish between the following calls:

|>> >  int foo();
|>> foo();

|>> > and
|>> and

|>> >  SomeClass& foo();
|>> foo();

|> These contradictions can always be resolved via
|>     (int)foo();
|>     (SomeClass&)foo();

|> So u need another argumentation to reject the result overloading.

And which function should be called here:

 (void)foo();

or here:

 float x = foo();

when SomeClass has operator float()?
--
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: ccshan@husc.harvard.edu (Chung-chieh Shan)
Date: 1996/10/23
Raw View
Igor Boukanov (boukanov@sentef1.fi.uib.no) wrote:
> These contradictions can always be resolved via
>     (int)foo();
>     (SomeClass&)foo();

Not exactly...  "(int)foo()" means you want to call some foo() and
*cast* the result to an int; "(SomeClass&)foo()" means you want to
call some foo() and *cast* the result to a SomeClass&.  The actual
return type of foo() is expressed nowhere.  (In fact, it makes more
sense for the programmer to write (int)foo() *if* s/he intends to
call the foo() that returns SomeClass&, since otherwise no cast
would be needed at all.)

--
blue | Ken; Shan, Chung-chieh; Sian7, Tiong1-kiat8; ccshan@fas.harvard.edu.
 ()  | Your code today becomes the mind tomorrow:  Your plan its means,
 /\  | your dream its ends, your ideal its elegance.  Hack on.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/10/24
Raw View
schwab@issan.informatik.uni-dortmund.de (Andreas Schwab) writes:

>Igor Boukanov <boukanov@sentef1.fi.uib.no> writes:
>
>|> These contradictions can always be resolved via
>|>     (int)foo();
>|>     (SomeClass&)foo();
>
>|> So u need another argumentation to reject the result overloading.
>
>And which function should be called here:
>
> (void)foo();
>
>or here:
>
> float x = foo();
>
>when SomeClass has operator float()?

These cases are obviously ambiguous, and should be rejected at
compile time.  But that is not a good argument against result
overloading; whenever you have overloading, there will be some
situations where you get ambiguity, and the programmer needs to
use an explicit typecast or something like that to resolve the
ambiguity.

Note that there are languages which support overloading on return type,
for example Ada 95.  But, as it says in the ARM (page 309):

 In general, however, [if overloading on return type is used]
 it is not that simple for humans or compilers to determine what
 the programmer really meant.
 Furthermore, allowing overloading based on the return type
 would invalidate the desirable property that C++ expressions
 can be analyzed bottum up looking at only a single operator and
 its operands at a time.

I think Stroustrup made the right design choice for C++ here.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: boukanov@sentef2.fi.uib.no (Igor Boukanov)
Date: 1996/10/24
Raw View
Andreas Schwab (schwab@issan.informatik.uni-dortmund.de) wrote:
> And which function should be called here:
>  (void)foo();
> or here:
>  float x = foo();
> when SomeClass has operator float()?

None. A compiler should produce an error in any case when there are the result
overloading and more than one implicit conversion to choose.
The same should take place for the call:
(void)foo();

And in this case (type)foo() should not mean cast operator, it just suggest
which function to select.

--
Regards, Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/21
Raw View
I wonder if anyone knows what the semantic constraint might be that decided
the return value would not participate in operator overload resolution.

Was it to do with built-in types?

In other words, why should these two NOT be distinct functions:

 int foo();
and
 SomeClass& foo();

If you were to define these now, the compile would complain that they had
an identical signature, right?

Dan
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]