Topic: operator overloading restrictions


Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 1 Sep 1994 10:05:53 GMT
Raw View
In article <33b80u$294@thecourier.cims.nyu.edu> osinski@cs.nyu.edu writes:
>In article <rfgCutqJH.G2M@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
>|> Actually, right about now, we who have looked at this problem (and that
>|> includes Sam Kendall, Martin O'Riordan, Jim Welch, Clark Nelson, and myself)
>|> *do* think we know what the the set of built-in operators, but expressing
>|> the requirements and restrictions on their operands is not always as easy
>|> as just writing a normal sort of function signature.  For example, how
>|> do you express the requirements (relating to type) for the LEFT operand
>|> of the comma operator?  ...
>
>Um, how about using the rules that the C standard uses?  Are they inadequate?

The ``rules of the C standard'' with respect to allowable operands of the
built-in operators are *not* the same as function signatures!

Try writing a prototype for a function and/or operator which can be passed
*any* scalar type.  When you get that done, please post it.

I hope you are getting my drift.  There are some notions which are meta-
linguistic with respect to C++, i.e. they cannot be directly represented
in the language itself (such as the notion of a parameter which can have
any arbitrary type).

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 1 Sep 1994 10:16:57 GMT
Raw View
In article <Cuzz3u.KnD@cdf.toronto.edu> g2devi@cdf.toronto.edu (Robert N. Deviasse) writes:
>In article <KANZE.94Aug23165956@slsvhdt.us-es.sel.de>,
>James Kanze US/ESC 60/3/164 #71425 <kanze@us-es.sel.de> wrote:
>>In article <33b80u$294@thecourier.cims.nyu.edu>
>>osinski@schonberg.cs.nyu.edu (Ed Osinski) writes:
>>
>>|> In article <rfgCutqJH.G2M@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
>>
>>    [concerning operators...]
>>|> |> Actually, right about now, we who have looked at this problem (and that
>>|> |> includes Sam Kendall, Martin O'Riordan, Jim Welch, Clark Nelson, and myself)
>>|> |> *do* think we know what the the set of built-in operators, but expressing
>>|> |> the requirements and restrictions on their operands is not always as easy
>>|> |> as just writing a normal sort of function signature.  For example, how
>>|> |> do you express the requirements (relating to type) for the LEFT operand
>>|> |> of the comma operator?  ...
>>
>>|> Um, how about using the rules that the C standard uses?  Are they inadequate?
>>|> I don't know what it says for the left operand of the comma operator, but how
>>|> about "anything (except void) goes"?
>>
>>In C, even void goes for the left operand of a comma.  But if you
>>define all possible types as built-in operators, then the user cannot
>>overload (which wasn't a particular problem in C).
>>
>
>Wouldn't this work? The compiler would predefine the following template:
>     template<class T,class U>
>       U& operator,(T&,U&);

Believe me.  Everyone's already though of that.

Templates are not sufficiently powerful, all by themselves, to express
all of the *kinds* of operand constraints which the language imposes.

Consider that case of the unary `!' operator.  It can take any _scalar_
operand.

Can you write that restriction into a template declaration?  I think not.

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 18 Aug 1994 04:40:47 GMT
Raw View
In article <KOHTALA.94Aug15214906@laurel.trs.ntc.nokia.com> Marko.Kohtala@ntc.nokia.com writes:
>Operators are allowed to be overloaded only if one of the arguments is
>a class or a reference to a class.
>
>I can see some reasons for not allowing overloading for built-in types
>like int, but can not see the reason to not allow for example:
>
> String operator+ (const char*, const char*);
>
>which does not have any built-in definition.
>
>What is the reason for this, or is this just a lapse in the standard?
>
>Can the rule be relaxed to say that operator overloading is allowed
>except when there is already an exactly mathing definition (whether
>built-in or user defined)?

That might be possible, but only *IF* the implicit prerequsite were
already satisfied.

The implicit prerequsite (in this case) is that there must exist a
complete list of exactly which built-in operators the language
already provides (along with their exact signatures).  You would need
such a list in order to know which operators (with which signatures)
were off-limits.

At the present time, the committee is still working on developing such
a list.  (It should also be noted that a great deal of progress was made
towards this goal at the last standardization meeting).

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 18 Aug 1994 23:24:17 GMT
Raw View
In article <rfgCupro0.80J@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>The implicit prerequsite (in this case) is that there must exist a
>complete list of exactly which built-in operators the language
>already provides (along with their exact signatures).  You would need
>such a list in order to know which operators (with which signatures)
>were off-limits.
>
>At the present time, the committee is still working on developing such
>a list.  (It should also be noted that a great deal of progress was made
>towards this goal at the last standardization meeting).

 It is nice to hear Ron say something positive about the
committee. Of course, Ron was on that working group himself :-)

 Yes, quite a lot of excellent progress was made at the
Waterloo meetting. We have even seen Hewlett Packard promise
to give away a major library (STL) to the world (Patented algorithms
included) for free. Thats probably the greatest achievement
in C++ since Bjarne wrote the ARM.

 Wonders will never cease :-)

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sat, 20 Aug 1994 08:06:53 GMT
Raw View
In article <330k0d$cna@thecourier.cims.nyu.edu> osinski@cs.nyu.edu writes:
>In article <rfgCupro0.80J@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
>|> The implicit prerequsite (in this case) is that there must exist a
>|> complete list of exactly which built-in operators the language
>|> already provides (along with their exact signatures)...
>
>Why don't we already know what the complete list is?  I mean, obviously we know
>that we can say "1 + 2", but not "p1 + p2", where p1 and p2 are pointers.  What
>combinations are we *not* sure of?

Well, it really depends on who you mean when you say ``we''.

Actually, right about now, we who have looked at this problem (and that
includes Sam Kendall, Martin O'Riordan, Jim Welch, Clark Nelson, and myself)
*do* think we know what the the set of built-in operators, but expressing
the requirements and restrictions on their operands is not always as easy
as just writing a normal sort of function signature.  For example, how
do you express the requirements (relating to type) for the LEFT operand
of the comma operator?  Similar (but worse) problems crop up for the ?:
operator because the second and third operands can be just about anything,
but their types have to match.  A whole different set of problems comes
up for the prefix/postfix ++ and -- operators (whose operands can be any
LVALUED scalar type).

So you see, it's largely a matter of expressing all these things in a
clear, concise, unambiguous, and (above all) correct way.

>In fact, how can one write a valid compiler
>if we doesn't know *exactly* what the built-in operations are?

Gosh!  I just can't imagine how.  Especially now that there are laws
requiring that all C++ compilers be totally flawless before they are
ever shipped to paying customers. :-) :-) (Yea.  Right.)

>Does the existing "standard" allow for some leeway?

I think it allows enough leeway to drive a MAC truck through.  Other
people disagree.

>Are the valid combinations in C++ different from those in C?

You bet.  Many of the built-in operators in C++ may be applied to operands
whose types don't even exist in C!

Furthermore, there are a number of (what I consider to be) throughly
pointless deviations from the C rules in the current draft C++ standard.
My favorite example of this is that in C++, unary + may be applied to
pointers.  What good this does for anybody I am unable to say.  I can
tell you one thing though.  The folks who brought you the C standard
were smart enough to know that if anybody *did* ever try to apply unary
+ to a pointer, it would probably indicate that the programmer in question
had been typing code without his/her glasses on... so the C standardization
committee wisely made such usage a constraint violation in C (subject to
a manditory diagnostic from all conforming compilers).

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: osinski@schonberg.cs.nyu.edu (Ed Osinski)
Date: 22 Aug 1994 22:14:54 GMT
Raw View
In article <rfgCutqJH.G2M@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
|> In article <330k0d$cna@thecourier.cims.nyu.edu> osinski@cs.nyu.edu writes:
|> >In article <rfgCupro0.80J@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
|> >|> The implicit prerequsite (in this case) is that there must exist a
|> >|> complete list of exactly which built-in operators the language
|> >|> already provides (along with their exact signatures)...
|> >
|> >Why don't we already know what the complete list is?  I mean, obviously we know
|> >that we can say "1 + 2", but not "p1 + p2", where p1 and p2 are pointers.  What
|> >combinations are we *not* sure of?
|>
|> Well, it really depends on who you mean when you say ``we''.

I meant C++ programmers who were relatively familiar with the language.

|> Actually, right about now, we who have looked at this problem (and that
|> includes Sam Kendall, Martin O'Riordan, Jim Welch, Clark Nelson, and myself)
|> *do* think we know what the the set of built-in operators, but expressing
|> the requirements and restrictions on their operands is not always as easy
|> as just writing a normal sort of function signature.  For example, how
|> do you express the requirements (relating to type) for the LEFT operand
|> of the comma operator?  ...

Um, how about using the rules that the C standard uses?  Are they inadequate?
I don't know what it says for the left operand of the comma operator, but how
about "anything (except void) goes"?

|>                    ...  Similar (but worse) problems crop up for the ?:
|> operator because the second and third operands can be just about anything,
|> but their types have to match.  ...

Well, it looks like you've just stated the correct rule.  Again, isn't what the
C standard says almost enough for C++?  (Remember, I'm talking about the
built-in definitions only.)

|>                            ...  A whole different set of problems comes
|> up for the prefix/postfix ++ and -- operators (whose operands can be any
|> LVALUED scalar type).
|>
|> So you see, it's largely a matter of expressing all these things in a
|> clear, concise, unambiguous, and (above all) correct way.

I take it you think they aren't.

|> >In fact, how can one write a valid compiler
|> >if we doesn't know *exactly* what the built-in operations are?
|>
|> Gosh!  I just can't imagine how.  Especially now that there are laws
|> requiring that all C++ compilers be totally flawless before they are
|> ever shipped to paying customers. :-) :-) (Yea.  Right.)

Maybe I'm being dense, but the examples you've given above seem to be of the
sort where most people know what the rules are or ought to be, but getting
wording worthy of being placed into the language reference may be a bit tricky.

As your examples above show, some of the rules for allowable combinations
cannot be expressed by a finite number of signatures within the C++ type
system, but (I thought that) C/C++ programmers know what is and what isn't
legal.  (An example of a rule not expressible in this way is the one for
operator ?:

 T operator?: (bool, T, T);   // for all T

The comment makes it clear what we mean, but it is not semantically
significant.)

Is this the major problem?

We (meaning persons programming in C++) all know of a large set of built-in
operator signatures which we are sure are legal, eg.

 int operator+ (int, int);
 double operator+ (double, double);
 ... long list not typed in for brevity ...

The aforementioned we also know of a set of operator signatures which we are
sure are *not* built-in, eg.

 operator+ (T *, T *);   // for any T
 ...

Can you think of any specific operator signatures whose legality a good C++
programmer is unsure of?

|> >Does the existing "standard" allow for some leeway?
|>
|> I think it allows enough leeway to drive a MAC truck through.  Other
|> people disagree.

Again, can you give a specific example of an expression using built-in types
and operators whose legality is questionable?

|> >Are the valid combinations in C++ different from those in C?
|>
|> You bet.  Many of the built-in operators in C++ may be applied to operands
|> whose types don't even exist in C!

Are you talking about built-in types?  I thought that C and C++ were the same
in this regard, with the minor exception of bool, and possibly enums.

--
---------------------------------------------------------------------
 Ed Osinski                  |
 Computer Science Department | "Do I know you?
 New York University         |  And don't try to deny it!"
 E-mail:  osinski@cs.nyu.edu |                 Col. Flagg to Hawkeye
---------------------------------------------------------------------




Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 24 Aug 1994 19:36:43 GMT
Raw View
In article <Cuzz3u.KnD@cdf.toronto.edu> g2devi@cdf.toronto.edu (Robert
N. Deviasse) writes:

|> Wouldn't this work? The compiler would predefine the following template:
|>      template<class T,class U>
|>        U& operator,(T&,U&);

You cannot have a reference to void, but the first parameter of an
operator, can be void.  (Of course, you cannot emulate this aspect
with a user defined overload.)
--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: kohtala@laurel.trs.ntc.nokia.com (Kohtala Marko)
Date: 15 Aug 1994 18:49:05 GMT
Raw View
Operators are allowed to be overloaded only if one of the arguments is
a class or a reference to a class.

I can see some reasons for not allowing overloading for built-in types
like int, but can not see the reason to not allow for example:

 String operator+ (const char*, const char*);

which does not have any built-in definition.

What is the reason for this, or is this just a lapse in the standard?

Can the rule be relaxed to say that operator overloading is allowed
except when there is already an exactly mathing definition (whether
built-in or user defined)?

I realise there may not be many uses for this besides the one in the
example, and most uses are bad and misleading kind. But since C++ is
not designed for idiots in other places, why should it be here?
--
---
Marko Kohtala - Marko.Kohtala@ntc.nokia.com, Marko.Kohtala@hut.fi




Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 16 Aug 1994 16:33:12 GMT
Raw View
In article 94Aug15214906@laurel.trs.ntc.nokia.com, kohtala@laurel.trs.ntc.nokia.com (Kohtala Marko) writes:
>Operators are allowed to be overloaded only if one of the arguments is
>a class or a reference to a class.
>
>I can see some reasons for not allowing overloading for built-in types
>like int, but can not see the reason to not allow for example:
>
> String operator+ (const char*, const char*);
>
>which does not have any built-in definition.

Different sets of operators are predefined for different built-in data
types. If we allowed user-defined operators for the cases where there
was not a predefined operator already, we would have to
- document in the language definition every combination of built-in type and
  operator to say whether it is overloadable;
- teach this complexity;
- increase the complexity of compilers in what is already one of the most
  complex parts of the compiler (operator and function overloading).

In exchange, you could write a pointer-add operator, and so forth. Are there
workarounds for the lack of this facility? Yes, you can create a class that
acts like a pointer (or whatever) and has whatever operations you would
like.

Whether to compilicate the language to make life more convenient for those
who want to add pointers (for example) was one of many design decisions in
C++. Individuals might disagree on whether this was the right choice, but I
think it was. The language is complicated enough already.

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