abuse of conditional operators (fwd)

D

Dan Noland

A friend of mine asked me a C question that I couldn't answer. Could
you guys weigh in?

---------- Forwarded message ----------
Date: Sun, 21 Nov 2004 21:08:27 -0500
From: Rick Kennell <[email protected]>
To: (e-mail address removed)
Subject: abuse of conditional operators

I was pretty bemused a few years ago when I was writing a compiler and
found out that some people expected this to work:

a ? b : c = d;

i.e. if 'a' is non-zero, assign 'd' to 'b', otherwise assign 'd' to 'c'.
Technically, there's no guarantee of support for this since X3J11
specifically claims that the conditional operator does not yield an
lvalue. GCC handles it and modern versions at least warn that this it's
deprecated behavior. TCC silently bungles it. I don't know about other
compilers.


So yesterday, I was reading LKML and came across someone who broke a
code-checking system because something was coded as:

a = b ? : c;

Specifically, the code was:

int tickadj = 500/HZ ? : 1;

which sets tickadj either to 500/HZ or to 1 if HZ is larger than 500.

Effectively, this means that

a = b ? : c;

is equivalent to

a = b ? b : c;

Neither the original K&R nor my copy of X3J11 say nothing about this.
There is a note about it in the GCC documentation

http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Conditionals.html#Conditionals

but it doesn't say anything about C99. Am I correct in assuming it's
just a GCCism?

Rick
 
R

Richard Bos

Dan Noland said:
I was pretty bemused a few years ago when I was writing a compiler and
found out that some people expected this to work:

a ? b : c = d;

i.e. if 'a' is non-zero, assign 'd' to 'b', otherwise assign 'd' to 'c'.
Technically, there's no guarantee of support for this since X3J11
specifically claims that the conditional operator does not yield an
lvalue.

So yesterday, I was reading LKML and came across someone who broke a
code-checking system because something was coded as:

a = b ? : c;

That's a syntax error. Possibly Ganuck allows it; ISO does not, neither
C89 nor C99.

Richard
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Richard said:
That's a syntax error. Possibly Ganuck allows it; ISO does not, neither
C89 nor C99.


Ganuck (LOL:) allows it. from
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Conditionals.html#Conditionals

5.8 Conditionals with Omitted Operands

The middle operand in a conditional expression may be omitted. Then if
the first operand is nonzero, its value is the value of the conditional
expression.

Therefore, the expression

x ? : y

has the value of x if that is nonzero; otherwise, the value of y.

This example is perfectly equivalent to

x ? x : y

In this simple case, the ability to omit the middle operand is not
especially useful. When it becomes useful is when the first operand
does, or may (if it is a macro argument), contain a side effect. Then
repeating the operand in the middle would perform the side effect twice.
Omitting the middle operand uses the value already computed without the
undesirable effects of recomputing it.
[END QUOTE]

Why they chose to "extend" the language like this is beyond me, since it
should be very easy to use standard C and still avoid any recomputations.

Bjørn
 
S

Sascha Springer

Dan said:
Specifically, the code was:

int tickadj = 500/HZ ? : 1;

which sets tickadj either to 500/HZ or to 1 if HZ is larger than 500.

Huh, I would rather guess the purpose is to avoid a division by zero!?

So it should be read as: 500/(HZ ? : 1)

Sascha
 
R

Richard Bos

Sascha Springer said:
Huh, I would rather guess the purpose is to avoid a division by zero!?

So it should be read as: 500/(HZ ? : 1)

Except that / binds more strongly than ?:, so the correct reading really
is (500/HZ)? : 1;
I suspect your reading, while not what it says, is what was intended.
Still a syntax error, though.

(And I note that the Ganuck construction X? : Y, for any X and Y
possibly including side-effects, can be trivially written in real C as
(tmp=X)? tmp: Y.)

Richard
 
K

Kenny McCormack

=?ISO-8859-1?Q?Bj=F8rn_Augestad?= said:
Why they chose to "extend" the language like this is beyond me, since it
should be very easy to use standard C and still avoid any recomputations.

I applaud GCC and it's very successful efforts to embrace and extend
minimalist^Wstandard C.

Ever hear of this company called, er, what was that now, oh, yeah,
Microsoft? They wrote the book on e&e.
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

Dan said:
A friend of mine asked me a C question that I couldn't answer. Could
you guys weigh in?

---------- Forwarded message ----------
Date: Sun, 21 Nov 2004 21:08:27 -0500
From: Rick Kennell <[email protected]>
To: (e-mail address removed)
Subject: abuse of conditional operators

I was pretty bemused a few years ago when I was writing a compiler and
found out that some people expected this to work:

a ? b : c = d;

i.e. if 'a' is non-zero, assign 'd' to 'b', otherwise assign 'd' to 'c'.
Technically, there's no guarantee of support for this since X3J11
specifically claims that the conditional operator does not yield an
lvalue. GCC handles it and modern versions at least warn that this it's
deprecated behavior. TCC silently bungles it. I don't know about other
compilers.


So yesterday, I was reading LKML and came across someone who broke a
code-checking system because something was coded as:

a = b ? : c;

Specifically, the code was:

int tickadj = 500/HZ ? : 1;

Yes. GCC extensions
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Lvalues.html#Lvalues
and
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Conditionals.html#Conditionals
 
M

Martin Ambuhl

Dan Noland wrote:
[...]
but it doesn't say anything about C99. Am I correct in assuming it's
just a GCCism?

If you compile using gcc with --std=c89 or --std=c99 (perhaps also -W
-Wall as well; I didn't check since I always use these), gcc will tell
you that these features are either deprecated or non-standard. Don't
use them if you want portably maintainable code.
 
T

Trent Buck

Quoth Martin Ambuhl on or about 2004-11-24:
If you compile using gcc with --std=c89 or --std=c99 (perhaps also -W
-Wall as well; I didn't check since I always use these), gcc will tell
you that these features are either deprecated or non-standard. Don't
use them if you want portably maintainable code.

Does GCC *guarantee* to notify you? I had understood that it would only
*try* to notify you.

-trent
 
D

Dave Vandervies

[Mind followups. Not sure where this would be topical; nowhere I follow,
since it's more of a pet peeve than an actual interest.]

I applaud GCC and it's very successful efforts to embrace and extend
minimalist^Wstandard C.

Ever hear of this company called, er, what was that now, oh, yeah,
Microsoft? They wrote the book on e&e.

You appear to be under the misconception that the GCC folk have (or should
have) any desire to uphold standards. Stallman and company are no less
interested in locking people into their software than Gates and company
are in locking people into theirs; portability and interoperability are
for wimps who might decide that there's something better out there and
want to give up on The One True Way.


dave
(For values of `One True Way' appropriate to the subject, of course.)
 
R

Richard Bos

I applaud GCC and it's very successful efforts to embrace and extend
minimalist^Wstandard C.

Ever hear of this company called, er, what was that now, oh, yeah,
Microsoft? They wrote the book on e&e.

Micro$oft wrote E&E edition 1. The Gnu guys wrote edition 2, and added a
fat appendix on "How to play the good guy while using the commercial
bastards' methods".

Richard
 
D

Dave Thompson

<OT implementation=gcc>
Ganuck (LOL:) allows it [as an extension]. from
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Conditionals.html#Conditionals

5.8 Conditionals with Omitted Operands

The middle operand in a conditional expression may be omitted. Then if
the first operand is nonzero, its value is the value of the conditional
expression.
Why they chose to "extend" the language like this is beyond me, since it
should be very easy to use standard C and still avoid any recomputations.
I have always suspected, but I can't prove, it was because it makes
C's ?: behave more like the COND form in LISP. Whether that is, or
would be, a good thing is up to each viewer. I do sometimes treat C
pointers as semipredicate, with null (canonically NULL) for NIL. FWIW.

- David.Thompson1 at worldnet.att.net
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top