Re: "Interesting" C behaviours
From: Chris Torek (nospam_at_torek.net)
Date: 11/27/04
- Next message: Rennie deGraaf: "Re: "Interesting" C behaviours"
- Previous message: Barry Schwarz: "Re: Typecasting Pointers"
- In reply to: Rennie deGraaf: ""Interesting" C behaviours"
- Next in thread: Erik Trulsson: "Re: "Interesting" C behaviours"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 27 Nov 2004 06:44:25 GMT
In article <sBUpd.360758$%k.84068@pd7tw2no>
Rennie deGraaf <ca.ucalgary.cpsc@degraaf> wrote:
>In the last few days, I have discovered two "interesting" behaviours of
>the C language, both of which are apparently correct. Could someone
>please explain the reasoning behind them?
>
>1. The operators '^', '&', and '|' have lower precedance than '==',
>'!=', '>=", etc. I discovered this when the statement "if (array1[i] ^
>array2[i] == 0xff)" failed to do what I expected. To me, it doesn't
>make any sense to give the bitwise operators lower precedance than
>comparators. I can't see any situation where someone would want to
>perform a bitwise operation on a truth value, but that is what the
>language specifies for the above expression.
Dennis Ritchie has noted that, in Primeval C, there were no "&&" and
"||" operators at all, and the single "&" and single "|" operators
were overloaded, so that:
result = f() | g();
would call both f() and g(), and bitwise-OR the results together to
store in the variable "result", while:
if (f() | g())
would call f() first, and if the result was nonzero, would omit the
call to g() entirely (i.e., what || does now). Likewise:
result = f() & g();
always called both, while:
if (f() & g())
called g() only if f() returned a nonzero value. Stopping as soon
as the result is known is called "short-circuit behavior". Presumably
the operators' priorities were set based on the short-circuit
versions, which probably occurred more often.
At some point, it was deemed bogus to have a single operator for
two entirely separate meanings, so the short-circuit logical
operators were separated out into new && and || operators. But by
then there were perhaps a few dozens of kilobytes :-) of source
code, so the operator parsing was left unchanged.
>2. In C99, the expression 'a%b' where a<0 and b>0 will return a negative
>result (K&R lets this be machine dependent). While it is technically
>correct (-1 is congruent to 6 mod 7), it isn't exactly what most people
>expect.
I think you have overly high expectations of "most people" here. :-)
>Mathematically, the congruence classes modulo n are usually
>expressed as [0], [1], ... [n-1].
True; but the "%" operator is really the "remainder after division"
operator. The goal is to have (a/b + a%b) == a, whenever b != 0.
To have ((-3) % 7) == 4, we would have to have ((-3) / 7) == -1),
but 0 is the most common result today for this division. Thus,
machines with "remainder after divide" instructions mostly produce
-3 here, and machines without such an instruction require computing
(a % b) via (a - (a / b) * b) in the first place.
-- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: forget about it http://web.torek.net/torek/index.html Reading email is like searching for food in the garbage, thanks to spammers.
- Next message: Rennie deGraaf: "Re: "Interesting" C behaviours"
- Previous message: Barry Schwarz: "Re: Typecasting Pointers"
- In reply to: Rennie deGraaf: ""Interesting" C behaviours"
- Next in thread: Erik Trulsson: "Re: "Interesting" C behaviours"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|