Conrad Weisert, July 1, 2011
| "Until you have inspected your [C++] data types, you have absolutely no
idea what + might do to them"
—Poul-Henning Kamp: "Sir, Please Step Away from the ASR-33!", Communications of the ACM, November, 2010, p. 57 |
Nonsense! We tried to bury that old canard a dozen years ago ("Why Can't Authors Get Operator Overloading Right?"), but it resists rational discussion. We most certainly do have a very clear idea what the plus sign does in any program written by a sane programmer.
In the expression a+b if a and b are numeric data items, the plus sign means addition. The program reader can depend on the result being the sum of a and b.
Yes, it's possible for a programmer to define + to
mean subtraction
or maximum, but such bizarre misuse is no more
likely than giving a named function a misleading name. A programmer who did either should
enjoy a short career.
It's also reasonable to expect that the operation is commutative
(a+b = b+a) and (barring overflow) associative
(a+(b+c)=(a+b)+c).
When operator overloading was added to C++, an obvious first project was to define a
character String class that would liberate
programmers from C's ugly and error-prone pseudo character strings. Since a
concatenation operator is essential, class developers looked at extended BASIC,
which used +, and at PL/I, which used
||. Either would have worked, but
|| had the wrong precedence relative to the
relational operators, so the plus sign was chosen and eventually got into the standard library.
So, in the expression a+b if a and b are String data items, the plus sign means concatenation. The program reader can assume that the result is the right operand appended to the end of the left operand.
We can safely assume that the operation is associative but not commutative.
We see that the quotation at the beginning of this article is invalid when the operands of
the + operator are both numeric or both String.
But what happens when we have one numeric operand and one String operand?
In Java, the
toString function would automatically convert the
numeric one to a character string representation, and it's not always possible to convert
a string to a number. In C++ you can often mimic that behavior with single-parameter
constructors or explicit conversion operators. However, we note an interesting anomaly
in both languages:
s+(x+y)
yields "ABC5" while (s+x)+y
yields "ABC23"
Oops! Does that mean that associativity doesn't hold for the +
operatior? Not at all. An operator denoted by the plus sign is associative in all cases. The
confusion arises because two entirely different operators, addition and concatenation, are
represented by the same symbol. If the designers of C++ and Java had had a richer character
set available, they would have chosen a different symbol.1
An experienced programmer would be well-aware of this, and would avoid confusing the
reader (and himself) with s+x+y or similar
expressions. Explicit parentheses or separate statements are clearly called for.
It's natural to extend the meaning of +
to vectors, lists, and other containers. But that runs into a potential conflict:
Both interpretations are potentially useful, and one can argue for either. However,
alternative a has the clear advantage of being extendable to the other arithmetic
operators,
which wouldn't make sense for alternative b. It also can support one container
operand and one scalar operand in a natural way. Therefore we should prefer a named
method for the concatenation alternative, and whenever we see
+
with container operands, we're justified in assuming an element-by-element operation.
Really strange uses of + pop up more often in articles and textbooks than in the real programs we're trying to read. For example:
Money object to an
Account object to produce an
Account object with an updated
currentBalance
Note that those examples are neither commutative nor associative. They're just weird.
Such examples, atrocious as they are, don't justify the quotation at the beginning of this article. We need to be very concerned about the readability of programs written by competent programmers of all skill levels. Let's not worry about programs written by the utterly confused. Misleading operator definition is the least of their problems.
In a programming language that supports operator overloading, the function of
a + operator should be absolutely clear to
the source-code reader or maintenance programmer, provided only that the program was
written by a minimally competent and sensible programmer.
For the whole story on operator overloading, see Object Oriented Computation in C++ and Java
Last modified 1 July 2011
Return to technical articles .
Return to IDI home page.