C Traps and Pitfalls (1988) [pdf]
literateprogramming.com
literateprogramming.com
Compound assignment operators such as += are really multiple tokens. Thus,
a + /* strange */ = 1
means the same as
a += 1 <source>:3:11: error: expected primary-expression before '=' token
3 | a + = 1;
| ^I now doubt whether it's true for either language. gcc 11 does not treat i + = 8; as equivalent to i += 8;, I get the kind of error message I'd have expected to see prior to reading the article. This occurs even if passing -std=c89 (as C89 is the oldest version of the C language that it seems to support).
Perhaps it was true prior to the C89 standard?
[1] https://www.amazon.in/Expert-Programming-Peter-van-Linden/dp...
-1/2 = -0.5
floor of that is -1.
-1 >> 1 == -1
What's the issue? It's integers. The floor is implied.
Right shift is equivalent with division if integer division were defined in a way consistent with two's complement number encoding.
Alas, that is not true.
The integer division instructions of most CPUs have definitions that are inherited from extremely ancient computers that used sign-magnitude number encoding and they truncate the quotient towards zero. There are many possible definitions of integer division and this is one of the worst, by failing to have many of the desirable mathematical properties (for instance it partitions the integer numbers into equivalence classes that have different sizes, which is bad for something like a histogram).
The C language just inherits the bad integer division definition implemented in hardware, instead of using a better definition that would result in lower performance due to additional overhead. Therefore it ends with two different kinds of integer divisions, one for "/" and another for ">>", which coincide for non-negative numbers, but which differ for negative numbers.
In my opinion this is a mistake that exists in almost all programming languages. They should have used a better definition for the integer division and remainder operations than the one implemented in hardware. The use of integer division with negative numbers happens only seldom, so its performance is unlikely to be important, but giving more useful and consistent results can simplify some programs and avoid surprising bugs.
Now it has become a chicken and egg problem. The CPU hardware continues to implement the bad definition, because that is what the popular programming languages expect, while the programming languages continue to use the bad definition because it is implemented in hardware.
See "The Euclidean definition of the functions div and mod":