40

In the UNIX V7 version of the C language (but not yet in the V6 version), there were the /\ (min) and the \/ (max) operators. In the source of the scanner part of the compiler,

case BSLASH:
    if (subseq('/', 0, 1))
        return(MAX);
    goto unkn;

case DIVIDE:
    if (subseq('\\', 0, 1))
        return(MIN);
...

However, attempting to use them reveals that the corresponding part in the code generator is missing. Trying to compile

foo(a, b) { return a \/ b; } 

results in

1: No code table for op: \/

Granted, using the otherwise "magic" backslash character for those operators was not a good choice, but why abandon things half-way? I don't remember any mention of them in the literature. What's the story behind them? (Ken Thompson was reported — on another mailing list where I linked to this question — as saying that the piece of code is news to him.)

In the Xinu7 source dated 1986, the MIN and MAX operators in the parser are still there, and the code generation table still lacks the implementation.

In the "PDP-11 3+2" source, dated 1983, they are also there.

  • 1
    No, not really. Anyways, let met know when you find where it actually generates code for these operators. – Ross Ridge Nov 1 '17 at 3:11
  • 1
    These sources github.com/mortdeus/legacy-cc/blob/master/last1120c/c00.c claim to be "the very first..." and look very similar, but without a trace of "MIN" and "MAX" operators. To me, that looks like a hack that someone added for an architecture that would probably have benefitted from these operators. – tofro Nov 1 '17 at 11:38
  • 2
    It doesn't seem to be in K&R 2ed., does anyone have a copy of the first edition from 1978? – snips-n-snails Nov 1 '17 at 15:48
  • 2
    @traal: Nope, not in K&R 1st ed (yes, I checked). – Greg Hewgill Nov 1 '17 at 20:30
  • 1
    @RossRidge Alas, for foo(a, b) { return a \/ b; } I get 1: No code table for op: \/; similarly for /\. Looks like an unfinished project whose traces lingered for years in the source. – Leo B. Nov 1 '17 at 22:19
12

(speculation, but I'm pretty confident in it) Assuming \/ and /\ were actually used in early C to be max and min, someone probably quickly realized how totally stupid that symbology is. They look like the long-accepted boolean operators for OR () and AND (). Having something you've been taught since high school means AND now stands for min in C would have been an extremely bad idea. It is equivalent to a computer language designer deciding that, in their language, the plus symbol (+) should mean divide (÷).

  • 16
    Well, the OR and AND boolean operators are also the MAX and MIN operators for boolean values, so it does make a certain amount of sense. – Ross Ridge Nov 1 '17 at 17:05
  • 3
    @RossRidge okay, I'll accept that the numeric values for TRUE and FALSE are typically thought of as 1 and 0. And of course, 1 > 0, making 1 max, just as 1 ∨ 0 is true (1) . However, thinking of these boolean values as numbers is a mistake. I recognize that C does not have a boolean data bype, meaning that effectively, true could have a numeric value of 1 or -7 or any non-zero value. Here it becomes apparent that the concept of max as or is flawed. It becomes even messier with it being unclear whether the OR under consideration is a boolean or binary operation. – RichF Nov 2 '17 at 10:06
  • 4
    C syntax was cluncky and non-standard. ^ To mean XOR and | to mean OR, as well as == to mean equality and = to mean assignation are non-standard, and would have remained so if it weren't for C language's major influence. – Bregalad Nov 3 '17 at 12:31
  • 3
    @RichF That notation might not be extremely common, but it's fairly standard and well understood, eg in probability theory. It's a natural extension of OR and AND in fuzzy logic, too. Compare math.stackexchange.com/questions/32137/… – Fab Nov 9 '17 at 13:23
  • 4
    @RichF As Sebastian mentioned, there is a fairly deep connection between boolean algebra and order comparisons of numbers. In both the ordering of booleans and the ordering of integers, those operations being discussed correspond to the join operation and the meet operation, which are represented with exactly those two symbols (in ASCII form, here). In fact, I strongly suspect this is where those symbols came from UNIX V7 C. There are other important connections between true and false and integer math too (in particular, integer arithmetic mod 2). – David Nov 19 '17 at 6:45
5

Assuming these operators were part of "original C" (I don't think so, see some comments):

The main reason why these weren't followed up would probably be: C being what it is - a close-to-the-machine language - an operator in C would need to be aligned with at least some closely related machine instruction - Most of the C operators are.

I am not aware of any wide-spread architecture that had a machine instruction that produced the bigger (or smaller) of two values. Without that machine instruction, a compiler would have had to revert to compiler intrinsics, something that wasn't known as a concept back then (for good reasons).

I have the strong feeling that these operators were some sort of hack that was introduced (or partially introduced) to port C to some architecture that actually had such instructions, and then forgotten in the code. This text states, which might be a hint:

Also during this period [Unix kernel programmed in C for the first time], the compiler was retargeted to other nearby machines, particularly the Honeywell 635 and IBM 360/370;

  • 1
    Most of the C operators are but far from all. Conversion of the Boolean result of a comparison into an integer is a "compiler intrinsic". If you could write foo(a, b) { return a > b; } and that would compile into a sequence of instructions moving 0 or 1 into the return register, the incremental step to doing the same with one compared value or the other isn't that big. Wasn't Unix V7 originally PDP-11 only? – Leo B. Nov 1 '17 at 21:55
  • 1
    Neither Honeywell 635 nor IBM/360 had min/max instructions. I think it was a (side) project that was abandoned at a late stage (one missing part is templates in the code generation table), likely for size reasons. It is funny for how long that abandoned code lingered in the source. – Leo B. Nov 1 '17 at 22:40
  • Maybe one of the "non-particular" architectures had such an instruction? I understand this as a non-exhaustive list. – tofro Nov 2 '17 at 10:36
  • 1
    It's a myth that C operators had to be closely aligned to the machine language. – JeremyP Nov 2 '17 at 10:37
  • 2
    @Wilson For Z-80 (that wasn't really driving C development), yes, for PDP-11, no. – tofro Nov 5 '17 at 9:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.