I know I can do this:
if ((a == x) || (a == z) || (b == x) || (b == z))
but is there a way to shorten it like this:
if (a||b == x||z)
which doesn't work...i hope i'm not answering my own question...
I know I can do this:
if ((a == x) || (a == z) || (b == x) || (b == z))
but is there a way to shorten it like this:
if (a||b == x||z)
which doesn't work...i hope i'm not answering my own question...
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
No, you have to do it the long way.
In this example, will C skip evaluation of the other conditions should a==x?
Yes, if (a == x) is true then the other comparisons will not be evaluated.In this example, will C skip evaluation of the other conditions should a==x?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
A three-way tie! You all get a cookie!
Does the compiler 'unroll' compound evaluation statements in a manner like so:
to:Code:if ((a == x) || (a == z) || (b == x) || (b == z)) { /* do stuff */ }
I've never used goto so this could be wrong but you get the gist. And is this implementation defined so something like:Code:if (a == x) { goto dostuff; } else if (a == z) { goto dostuff; } else if (b == x) { goto dostuff; } else if (b == z) { goto dostuff; } goto dontdostuff: dostuff: /* do stuff */ dontdostuff: /* continue with rest of program */
Would result in undefined behavior? Will i++ not happen if a==x?Code:if ((a == x) || (i++ < 10))
I have no idea whether it gets unrolled, but it wouldn't surprise me.
The second is not undefined behavior, but i++ won't happen with a==x. (This is often used in things like
so that the dereference won't happen if intptr is NULL.Code:if (intptr == NULL || *intptr == 10)
more likeCode:if (a == x) { if (a == z) { if (b == x) { if (b == z) { /* do stuff */ } } } }
Last edited by robwhit; 08-28-2008 at 12:47 PM.
Wouldn't that be for &&?
Thanks, I was actually trying to think of a sane case where you would rely on this behavior.The second is not undefined behavior, but i++ won't happen with a==x. (This is often used in things like
so that the dereference won't happen if intptr is NULL.Code:if (intptr == NULL || *intptr == 10)
Oh yeah... haha...
Then yeah it would be similar to what you have there. Might not be the same thing, but similar. You could output assembly and see what it does.
To generate assembly with GCC, use the -S flag (note the uppercase 'S' -- lowercase 's' means strip symbols).
Note that you might want to disable optimisations, or enable them, depending on what you're interested in.Code:gcc -S source.c cat source.s
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
Here's the result (I just cut out the portion that looked meaningful):
Now I have about 10 minutes experience with assembly but it looks to be doing the same thing I unrolled in C. Except I used else needlessly.Code:/* C */ int a = 0, b = 1, x = 1, z = 0; if ((a == x) || (a == z) || (b == x) || (b == z)) a = 5; /* ASM */ movl $0, -4(%ebp) movl $1, -8(%ebp) movl $1, -12(%ebp) movl $0, -16(%ebp) movl -4(%ebp), %eax cmpl -12(%ebp), %eax je L3 movl -4(%ebp), %eax cmpl -16(%ebp), %eax je L3 movl -8(%ebp), %eax cmpl -12(%ebp), %eax je L3 movl -8(%ebp), %eax cmpl -16(%ebp), %eax je L3 jmp L2 L3: movl $5, -4(%ebp) L2: movl $0, %eax leave ret
Yeah, it is.
je stands for "jump if equal", and jmp is just jump.
Although GCC chose to do it the "other way" around than what I expected the compiled code to look like. But it doesn't matter, really. It works.
( Again, GCC's asm syntax sucks =( )