by Eric Sosman
April 1, 2010
Several recent threads, and for that matter a great number of threads in years past, have debated whether C should be extended to permit operator overloading. Proponents argue that overloading would improve readability by allowing a user-defined quaternion type (for example) to be manipulated with familiar arithmetic operators rather than with verbose sequences of function calls. Opponents say that overloading would, on the contrary, disimprove readability by making the ordinary + sign an uncertain symbol whose meaning can only be discovered by extensive detective work. Successive debates have trodden this same ground so often that it is now hard-packed, with no green and growing thing left upon it.
But the discussions thus far have ignored another vital matter, namely, the robustness of code that uses overloaded operators. After all, the "over" in "overload" doesn't just mean "more," but "too much more." An overloaded bridge may crumble and drown its traffic in the river below. Overload an electrical circuit and you'll get at best a blown breaker or perhaps a fire. We all know what happens when one last straw overloads the camel's back.
Any proposal to add operator overloading to C must therefore address the issue of catastrophic failure of operators under overload conditions. It turns out that at least some of C's operators are structurally delicate to the point of fragility, and cannot sustain overload as they stand.
The division operator is perhaps the most glaring example. It sits on a slant, its only support one lonesome pivot point on the baseline. Add even a small load to a / and it will topple to a _, completely changing its meaning -- in fact, transforming it from an operator to an identifier! The additional load acts through a lever arm that the unsupported division operator is powerless to resist.
Other operators may also be unable to sustain overload. It takes only a modest amount of pressure to flatten the kinks out of the bitwise complement operator ~ and make it indistinguishable from the - unary negation operator. The exclusive or ^ resists pressure somewhat better, but eventually it, too, collapses to -. So when a compiler encounters what looks like a -, it might be an actual - or an overloaded ~ or ^, and the compiler has no way to know what was intended. The best it can do may be to flip a three-sided coin (available at specialty stores) and choose randomly in hopes of being right some of the time.
Some operators suffer deformation but usually retain enough of their form to remain recognizable and useful. No amount of pressure will squeeze the . operator any smaller than it already is. The + operator might have an arm snapped off, but unless it loses both it will still be distinguishable from |. | itself may bend to resemble ( or ), but if the load is well-centered this will seldom happen. The * operator will get squashed to the semblance of a road-killed hedgehog, but will still be recognizable because no other operator flattens to that form.
How shall we address this precarious state of affairs? The first impulse may be to build the operators more sturdily, with heavier structural members. Instead of `x + y / z' we could write
||| /// ||| ///| ||| ///|| -----|||----- /// || x ------+------ y /// || z -----|||----- /// || ||| /// || ||| /// || ||| /// ||using thicker lines (and giving the division operator a much-needed stabilizing leg) to sustain higher loads than the wispy strokes of today's feeble glyphs can handle. But this approach is unsatis- factory because it does not scale to really large loads. For a two-dimensional figure like a source glyph, the cross-section (hence, the strength to sustain load) increases linearly with size, but the character's area (hence, mass) increases as the square. Thus, there's a built-in limit to how far this strategy can take us: At some point we'll need to make the symbol larger to support greater loads, but the increase in mass will add load faster than the growth in cross-section adds strength. The bloated operator will eventually collapse under its own weight. Growth is not the answer.
How about leaving the operators at (or near) their current sizes, but building them of sturdier stuff? Materials technology can now produce substances far stronger than were available four decades ago when C's operators were invented, things like rare-earth composites and carbon nanotubes. The noted Iraqi materials scientist Maq'it al-Egos graciously consented to study the problem.
He began by separating the question of stronger pixels from that of stronger print, since screen displays and paper-borne glyphs face radically different problems. On a screen, it turns out that the structural strength of a pixel depends mostly on its color. (He found it surprising that the display technology had relatively little to do with the matter; the same colors were strong or weak regardless of whether they were generated by liquid crystal, plasma, or cathode rays on phosphor.) The strongest pixels are almost white with a slight bluish tinge, easily produced on RGB displays by driving the blue component to its maximum while letting red and green hover a few percent below theirs.
There is an edge effect to worry about. Strong blue-white pixels adjacent to weaker-colored pixels are themselves weakened slightly, and they in turn weaken their stronger neighbors. If unchecked, weak pixels surrounding an operator painted in strong pixels will "corrode" the formerly-strong pixels and bring on the very collapse we're trying to prevent. But the counter-measure is simple: Paint the strong-pixel operator on a background of the same strong color, and there will be no such corrosive effect. The entire screen will be strong, able to sustain extreme loads easily. We can consider this problem solved.
The print question still resists solution. al-Egos has been able to develop sufficiently strong inks and toners, but has reached the point at which the paper itself fails and tears; the operators, even though intact, lose much of their readability when the paper they're printed on turns to powder. Experiments with rhodium foil as a paper substitute seem promising, but are at present in the early stages. The foil is rather expensive in laboratory quantities (around US$3 per square centimeter), but in commercial production we can expect the price to drop by half, perhaps even by two-thirds. Besides, printed books are going the way of the dinosaurs, so their durability is not all that great a concern.
The essay to this point would have been posted a couple weeks ago, but I mentioned the matter to my friend Druncan O'Blivion in a bar late at night on Saint Patrick's Day, and he came up with a radically different approach that needed additional study. I confess that my recollection of what he said that night is none too clear, but I still have the cocktail napkin on which he drew his diagrams and made his calculations. (I would post an image of the napkin, but Druncan also drew on it an astonishingly lifelike sketch of the barmaid, with details I presume are hypotheses rather than experimentally verified facts, and this is a family newsgroup.)
Druncan works for NASAL ("It *is* rocket science!" he likes to say), and his solution arises from astrophysics. He pointed out that the force of gravity varies as the inverse square of the distance between the attracting masses. A small mass at a great distance from a large attractor feels very little attractive force, and that small force can be resisted by even a feeble structure. Thus, we can overload our familiar operators, just as we know them today, provided we place them high enough that their loads are light and sustainable. The familiar quadratic formula can be written as
= - + ( * - * * ) / * x ( b sqrt b b 4 a c ) (2 a)improving structural integrity with only a small loss in clarity. In actual code one would use more vertical distance than in this condensed example, enough to put the operators into low Earth orbit where they would be in free fall and essentially gravityless.
Druncan pointed out that we must not go too high (although we were both rather high at the time), lest we place the operators in the Van Allen belts belts where radiation could damage them. For example, the commonest isotope of the right-shift operator, >>36, transmutes to the array-index operator 40 upon absorption of an alpha particle. This isotope of  is unstable and quickly decays to >> again, but to >>37 instead of >>36. Both >>36 and >>37 are stable isotopes and both are right-shift operators, but >>37 affects the sign bit differently. It may be that the existence of two stable >> isotopes is the cause of much of the confusion about the behavior of the shift operators.
(As a side-note, researchers at SCORN have been collecting code samples from Usenet and bombarding them with energetic electron beams. Preliminary reports indicate little change in code entropy, as most code samples are maximally chaotic to begin with. After irradiation, some code stops working altogether; the researchers indicate that this is usually an improvement. Further experiments are planned with heavy-particle beams, now that the Large Hardon Collider is, er, up.)
In summary, this note describes some of the structural challenges that must be considered when overloading C's operators. For screen display, painting the operators blue-white on a blue- white background seems an entirely satisfactory solution. For display on monochrome screens or to color-blind viewers, O'Blivion's technique can be used by any organization able to muster sufficient near-Earth throw weight. The matter of overloaded operators in print needs better solutions, but the authors of "C Unchained" will surely think of something in time for the next edition.
(This essay may be redistributed in electronic form without restriction. Each recipient is permitted to print one copy for his or her own personal use. All photocopies require individual licenses, from originator's own lawyers.)
This page was last updated April 1, 2010.