why did K&R make &&, || logical and &, | bitwise, not the other way around?

c, language-design

Solution

From the horse's mouth:

Rapid changes continued after the language had been named, for example the introduction of the `&&` and `||` operators. In BCPL and B, the evaluation of expressions depends on context: within if and other conditional statements that compare an expression's value with zero, these languages place a special interpretation on the and (`&`) and or (`|`) operators. In ordinary contexts, they operate bitwise, but in the B statement

    if (e1 & e2) ...

the compiler must evaluate `e1` and if it is non-zero, evaluate `e2`, and if it too is non-zero, elaborate the statement dependent on the if. The requirement descends recursively on `&` and | operators within `e1` and `e2`. The short-circuit semantics of the Boolean operators in such `truth-value' context seemed desirable, but the overloading of the operators was difficult to explain and use. At the suggestion of Alan Snyder, I introduced the `&&` and `||` operators to make the mechanism more explicit.

Remember that C wasn't created in a vacuum; much of its weirdness can be traced to BCPL and B.

Problem

I know that `==` was chosen for equality and `=` for assignment because they thought that people did more assignment than checking for equality---but surely they didn't think that there would be more bit fiddling than boolean logic? Why not go the other way around, with `&` and `|` being logical operators?

Original source