Garrett Cooper schrieb:
On Fri, Dec 5, 2008 at 1:11 AM, Christoph Mallon
<[EMAIL PROTECTED]> wrote:
Garrett Cooper schrieb:
(I feel like I'm getting off on a bikeshed topic, but...)

1. What dialect of C was it defined in? Is it still used in the
standard dialect (honestly, this is the first time I've ever seen it
before, but then again I am a younger generation user)?
Dialect? The ! operator is plain vanilla standard C. It takes a scalar
operand and returns 1, if it compares equal to 0, otherwise it returns 0.
!!, i.e. two consecutive ! operators, is one of the oldest tricks in the
book, right next to (a > b) - (a < b) for comparison functions and countless
other idioms.

3. What's the real loss of going to `? :', beyond maybe 3 extra
keystrokes if it's easier for folks who may not be as experienced to
read?
I'd like my bikeshed grass green, please.

       Christoph

If you really want to split hairs, ! only negates the logic value,
whereas ~ actually negates the bits. So technically, you're not
flipping 0 to make 1 and vice versa, but instead flipping 0 to make
non-zero, etc. There is a clear distinction in hardware.

I have no idea, what you are referring to. I did not even mention the bitwise complement operator ~. I just described, what ! does. I explicitely said, the operand is compared to 0. I just paraphrased, what the standard says. You can verify this by reading ISO/IEC 9899:1999 (E) §6.5.3.3:5.

The point was that !! isn't obvious at first glancing the C code. It's

I disagree. I sometimes even see stuff like (x ? 0 : 1) or worse (x ? false : true). I find this hard to read, because the "true" case returns "false" and vice versa. I clearly prefer a nice and concise ! or two. But today !! is not as important anymore, because C99 has a real bool type, which always is 0 or 1. See _Bool and the header <stdbool.h>.

important for code to be readable as well as functional (that's why we
have style(9)). Getting down to it I'd like to see what the compiler

Don't try to argue about style(9). IMO it's horribly outdated, but there are conservative forces, which would prefer to cling to K&R. At least we got function prototypes!

optimizes each as, because I can see dumb compilers saying `!!'
translates to `not, bne => set, else set, continue', whereas `? :'
could be translated to `bne, set, else set, continue'; I'm sure gcc
has moved passed these really minute details.

If you use the classic approach to implement short circuit evaluation for && and || you also handle !. Otherwise the code generated for stuff like if (!x || !y) would be horrible. Here's a very short explanation: You generate jump labels for the "true" and "false" cases. When traversing a logical expression and encountering a !, you just swap the "true" and "false" jump labels - nothing more happens for a !. So at no point you generate code, which produces a 0/1 and compares it again. While evaluating a logical expression with short circuit evaluation, there are no intermediate 0 and 1 constants involved at all. This is a very simpel model. Modern optimizing compilers do not generate code directly from the abstract syntax tree, but use a intermediate representation, which is more suited for optimization[1][2].

Hopefully this helps to shed a bit light on compiler construction.

        Christoph



[1] (self advertisement) FIRM is a modern graph based IR, which uses SSA form: http://www.libfirm.org/
[2] LLVM has a nice IR, too: http://www.llvm.org/
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to