Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ames!uhccux!munnari.oz.au!cs.mu.oz.au!ok From: ok@cs.mu.oz.au (Richard O'Keefe) Newsgroups: comp.lang.c Subject: Re: C history question Keywords: C design, XOR Message-ID: <2120@munnari.oz.au> Date: 16 Sep 89 09:12:26 GMT References: <575@calmasd.Prime.COM> <1687@sunset.MATH.UCLA.EDU> <174@cpsolv.UUCP> Sender: news@cs.mu.oz.au Lines: 29 In article <174@cpsolv.UUCP>, rhg@cpsolv.UUCP (Richard H. Gumpertz) writes: > I hate resorting to implementation arguments when discussing the design of a > language, but after all C does very much reflect its history as an > implementation language with few "expensive-to-implement" operations hidden > behind seemingly simple operators. This is not entirely true. For example, C inherited ++ and -- from B, which ran on a machine which didn't have auto-{in,de}crement. C and B both inherited their set of test&branch operations from BCPL, which was an implementation language for word-addressed machines (not even 360s!). BCPL had test&branch versions of AND and OR, but no test&branch version of XOR. There are quite a lot of cheap hardware instructions which C doesn't reflect at all (Rubin's complaint): e.g. PDP-11s have rotate instructions, but C has no "rotate" operator. Subscripts are a seemingly simple operator, but can involve shifts and multiplies which can be quite hairy, and floating-point arithmetic can hide very expensive operations behind seemingly simple operators. > As long as we are discussing missing "assignment" operators, you might ponder > the lack of unary assignment operators. Why should I have to say X = -X or > X = ~X? If you really don't want side-effects in X to be repeated, #define NegateVar(X) ((X) *= -1) #define ComplementVar(X) ((X) ^= -1) and then NegateVar(fred); /* has effect of fred = -fred; */ ComplementVar(jim); /* has effect of fred = ~fred; */ This is not hard.