Boolean OR (double pipe) and ISO C99

I

Ian Zimmerman

Hello, I hate to make a fool of myself, but:
in C99, is

var = ((exp1) || (exp2));

necessarily equivalent to

int temp = (exp1); var = (temp != 0 ? temp : (exp2));

as I believe it was in pre-99 C? gcc seems to compile it rather as

var = ((exp1) != 0 || (exp2) != 0)

ie. the final value of var is always 0 or 1.

If this latter translation is indeed correct, can anyone think of
a way to achieve the old effect without a temporary variable?
This code needs to go into a macro, and exp1 and exp2 are potentially
complex expressions involving function calls and side effects.
 
M

Michael Mair

Ian said:
Hello, I hate to make a fool of myself, but:
in C99, is

var = ((exp1) || (exp2));

necessarily equivalent to

int temp = (exp1); var = (temp != 0 ? temp : (exp2));

as I believe it was in pre-99 C?

It was not. || gives you 1 if one of its operands is
not equal to 0.
gcc seems to compile it rather as

var = ((exp1) != 0 || (exp2) != 0)

ie. the final value of var is always 0 or 1.

This is correct behaviour.
The standard did not change in that respect.
If this latter translation is indeed correct, can anyone think of
a way to achieve the old effect without a temporary variable?
This code needs to go into a macro, and exp1 and exp2 are potentially
complex expressions involving function calls and side effects.

Umh, I fear you will need some sort of "var" as above if you
do not want the whole thing too complicated.
I would either go for
(var=(exp1)) || (var=(exp2))
or
(var=(exp1)) ? (var) : (var=(exp2))
and pass var, calling the macro SET_VAR_....(var, ....)
or "return"
(var=(exp1)) ? (var) : (exp2)

<OT>
BTW: Within the last couple of months, there was a discussion
of a GNU extension which would have permitted you solving
your problem by (exp1)?:(exp2). Maybe you can find other
interesting arguments/alternatives there.

http://groups.google.de/[email protected]
</OT>


Cheers
Michael
 
J

Jack Klein

Hello, I hate to make a fool of myself, but:
in C99, is

var = ((exp1) || (exp2));

necessarily equivalent to

int temp = (exp1); var = (temp != 0 ? temp : (exp2));

No, the result of both the || and && operators has always been an int
with the value of 0 or 1.
as I believe it was in pre-99 C? gcc seems to compile it rather as

Where did you come up with this belief? It has never been correct.
var = ((exp1) != 0 || (exp2) != 0)

ie. the final value of var is always 0 or 1.

Yes, the final value must always be 0 or 1. From the day that these
operators were added to the language, before the publication of the
first edition of the C Programming Language in 1978.
 
I

Ian Zimmerman

Jack> No, the result of both the || and && operators has always been an
Jack> int with the value of 0 or 1.

Ian> as I believe it was in pre-99 C? gcc seems to compile it rather as

Jack> Where did you come up with this belief? It has never been
Jack> correct.

From reading and writing too much Lisp/Scheme, no doubt.
;-)

Anyway, I found a workaround with a bit of refactoring; the function call
in exp2 now takes the value of exp1 as an argument, and does nothing if
the latter is nonzero.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top