[comp.lang.c] cond. op. on ='s LHS

burow@cernvax.cern.ch (burkhard burow) (02/14/91)

I'm wondering if anyone has any comments on using:

       *(a==b?&c:&d) = 1;

instead of:

       if (a==b) c=1;
       else      d=1;

thanks, burkhard  burow%13313.hepnet@csa3.lbl.gov

johnm@cory.Berkeley.EDU (John D. Mitchell) (02/14/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>       *(a==b?&c:&d) = 1;
>instead of:
>       if (a==b) c=1;
>       else      d=1;

1) Readability, readability, READABILITY!

2) Why?  It's not any faster.

Ugh,
	John D. Mitchell
	johnm@cory.Berkeley.EDU

P.S.	No wonder people complain about the denseness of C code!

gwyn@smoke.brl.mil (Doug Gwyn) (02/14/91)

In article <11073@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John D. Mitchell) writes:
- In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
- >I'm wondering if anyone has any comments on using:
- >       *(a==b?&c:&d) = 1;
- >instead of:
- >       if (a==b) c=1;
- >       else      d=1;

My comment was going to be that it sucked bigtime.  However, I'll
buy "ugh" as a suitable comment too.

- P.S.	No wonder people complain about the denseness of C code!

C code has nothing to do with it, more like the density of some coders.

paulb@ssd.csd.harris.com (Paul Beusterien) (02/14/91)

In article <11073@pasteur.Berkeley.EDU>  johnm@cory.Berkeley.EDU (John D. Mitchell) writes:
:In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
::I'm wondering if anyone has any comments on using:
::       *(a==b?&c:&d) = 1;
::instead of:
::       if (a==b) c=1;
::       else      d=1;
:
:1) Readability, readability, READABILITY!
:
:2) Why?  It's not any faster.

Its probably slower, since it is a lot less likely the compiler
will keep c and d in registers.
--
Paul Beusterien                          paulb@ssd.csd.harris.com
Harris Computer Systems        {uunet,mit-eddie,novavax}!hcx1!paulb
Ft. Lauderdale, FL                     voice: (305) 973 5270

kdq@demott.com (Kevin D. Quitt) (02/14/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>
>       *(a==b?&c:&d) = 1;
>
>instead of:
>
>       if (a==b) c=1;
>       else      d=1;

    It's cryptic and ugly, therefore harder to maintain.  It also produces
identical code (gcc, MSC 6.0).  It *does* save several bytes of storage.



-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

ckp@grebyn.com (Checkpoint Technologies) (02/14/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>
>       *(a==b?&c:&d) = 1;
>
>instead of:
>
>       if (a==b) c=1;
>       else      d=1;

Sure, I have a comment. My own opinion, of course, since both are valid
C and should produce identical results.

In nearly all cases I would use the second form. It's easier to read.
In fact I had to go over the first one twice to assure myself that it
does what the second clearly states, and clarity is a critical feature
of any program.

Note also that the first form won't necessarily work if either c or d
are register variables.

The only time I would use the first form is in a macro, in a situation
where I really wanted an expression rather than a statement.  But that's
all.
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

karl@ima.isc.com (Karl Heuer) (02/14/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>       *(a==b?&c:&d) = 1;

What you really want is
	(a==b?c:d) = 1;
which should (IMHO) be legal (i.e. the result of ?: is an lvalue if both
subexpressions are lvalues), but this isn't the case in Standard C.  (But
GCC supports it as a non-standard extension.)

So far everyone has complained about using ?: instead of the "clearer" method
of putting the assignment inside the conditional.  Nobody has mentioned yet
that the above form does have one advantage, which becomes more obvious when
the RHS is a complicated expression: you can write it just once without using
a temporary.

If the GCC extension were standard, I'd use it in such a case (just as I use
x=(a==b?c:d) in real C when appropriate).  But since it isn't, and making it
legal by adding the extra *...&...& is a lose, I'd probably declare a temp
variable and use (a==b?c=T:d=T) instead.  (Or the equivalent if-else form, if
it's in a statement context.)

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint

suhonen@kunto.jyu.fi (Timo Suhonen) (02/14/91)

burow@cernvax.cern.ch (burkhard burow) writes:

   I'm wondering if anyone has any comments on using:

	  *(a==b?&c:&d) = 1;

   instead of:

	  if (a==b) c=1;
	  else      d=1;


OK. I have one: The if - else -statement is much more readable than the other
one. Have look with a compiler wich one if faster...

--
Timo Suhonen        I am logged in, therefore I am        suhonen@nic.funet.fi
                                                          suhonen@kunto.jyu.fi
   Opinions(?) are mine (if not stolen), NOT those of Univ. of Jyvaskyla.

johnm@cory.Berkeley.EDU (John D. Mitchell) (02/14/91)

In article <15184@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <11073@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John D. Mitchell) writes:
[....]
>My comment was going to be that it sucked bigtime.  However, I'll
>buy "ugh" as a suitable comment too.

I decided that sucked s#!t was too harsh.  :-)

>- P.S.	No wonder people complain about the denseness of C code!
>C code has nothing to do with it, more like the density of some coders.

Well, a lot of people (wrongly) criticize the *language* when it's really
the (your flame here) coder that makes the source code atrocious.  I mean,
we're not talking about entries for the obfuscated C code contest!

----	John D. Mitchell
	johnm@cory.Berkeley.EDU

richard@aiai.ed.ac.uk (Richard Tobin) (02/14/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>
>       *(a==b?&c:&d) = 1;

Yes, it's ugly and pointless, and furthermore prevents c and d from
being in registers.

By the way, gcc allows as an extension

    (a == b ? c : d) = 1;

which is much more reasonable.

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

volpe@camelback.crd.ge.com (Christopher R Volpe) (02/14/91)

In article <15184@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
|>In article <11073@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John
D. Mitchell) writes:
|>- In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard
burow) writes:
|>- >I'm wondering if anyone has any comments on using:
|>- >       *(a==b?&c:&d) = 1;
|>- >instead of:
|>- >       if (a==b) c=1;
|>- >       else      d=1;
|>
|>My comment was going to be that it sucked bigtime.  However, I'll
|>buy "ugh" as a suitable comment too.

Yes, it's ugly, but it's conceivable that someone might have a good
reason for defining a macro to do this, so that the macro may be used
in an expression context.              
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

johnm@cory.Berkeley.EDU (John D. Mitchell) (02/15/91)

In article <16754@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com (Christopher R Volpe) writes:
[....]
>Yes, it's ugly, but it's conceivable that someone might have a good
>reason for defining a macro to do this, so that the macro may be used
>in an expression context.              

Aahhh!  But context *is* everything.

One reason to use macros is to hide this sort of cryptic code behind
a nice facade.  Oh well... if only C had...  :-)

----	John D. Mitchell
	johnm@cory.Berkeley.EDU

scc@rlgvax.Reston.ICL.COM (Stephen Carlson) (02/15/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>
>       *(a==b?&c:&d) = 1;
>instead of:
>       if (a==b) c=1;
>       else      d=1;
>

The GNU C compiler as an extension to the C programming language allows the
result of the ternary operator to be an lvalue:

	((a == b) ? c : d) = 1;

Normal C, however, requires that the result of the ternary operator be an
rvalue, hence the subterfuge with the & and * operators (the result of a
* operator is an lvalue).

My only remark is that this may be preferable in the case where the right
hand of side of the expression is some long expression, like:

	*(a==b?&c:&d) = some_long_and_hairy_expression;

Since it written only once and not twice, there is less chance for errors
due to inconsistencies, as in:

	if (a == b) c = some_long_and_hairy_expression;
	else        d = some_lomg_and_hairy_expression;

Here, those two long expressions are not the same and it is not clear to the
maintainer whether they should be the same.  To paraphrase Aristotle, same
things should be the same; different things different.  The same argument is
the basis for the += type of operators:

	some_long_and_hairy_lvalue += 2;

is better than:

	some_long_and_hairy_lvalue = some_long_and_hairy_lvalue + 2;


Of course, since this subterfuge is especially convultuted and hairy, I
would reccommend:

	e = some_long_and_hairy_expression;
	if (a == b)
		c = e;
	else
		d = e;

Here, it is clear that either c or d are to be assigned to the same
expression in either case.  A good compiler will put the value in a
temporary anyway.

-- 
Stephen Carlson            | ICL OFFICEPOWER Center
scc@rlgvax.opcr.icl.com    | 11490 Commerce Park Drive
..!uunet!rlgvax!scc        | Reston, VA  22091

volpe@camelback.crd.ge.com (Christopher R Volpe) (02/15/91)

In article <11129@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John
D. Mitchell) writes:
|>In article <16754@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com
(Christopher R Volpe) writes:
|>[....]
|>>Yes, it's ugly, but it's conceivable that someone might have a good
|>>reason for defining a macro to do this, so that the macro may be used
|>>in an expression context.              
|>
|>Aahhh!  But context *is* everything.

Huh??? So, like, what's your point?

|>
|>One reason to use macros is to hide this sort of cryptic code behind
|>a nice facade.  Oh well... if only C had...  :-)

Isn't that what I suggested? Again, I'm unclear as to what you're trying
to say. Are you agreeing? Disagreeing? And what is it that you wish C had?

|>
|>----	John D. Mitchell
|>	johnm@cory.Berkeley.EDU
             
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

rmartin@clear.com (Bob Martin) (02/15/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>
>       *(a==b?&c:&d) = 1;
>
>instead of:
>
>       if (a==b) c=1;
>       else      d=1;
>
>thanks, burkhard  burow%13313.hepnet@csa3.lbl.gov

Burkhard:

There are a number of disadvantages to the first case above.  I will discuss
the least important ones first.

1. It probably generates more code.  The pointer operations will force the
   poor compiler to generate pointer references and dereferences.

2. It wont work if c or d happen to be register variables.

3. It wont work if c and d are of different types. (i.e. int c; double d;)

4. It is cryptic.

In general it is not true that code gets better if you remove whitespace, or
use clever little tricks.  With a few notable exceptions, the most important
feature of code (other than that it should work) is that it should be
easy to read and understand.  Unless you are horribly pressed for execution
speed or memory space, you should be willing to make concessions to these
goals for the goal of readability.

-- 
+-Robert C. Martin-----+:RRR:::CCC:M:::::M:| Nobody is responsible for |
| rmartin@clear.com    |:R::R:C::::M:M:M:M:| my words but me.  I want  |
| uunet!clrcom!rmartin |:RRR::C::::M::M::M:| all the credit, and all   |
+----------------------+:R::R::CCC:M:::::M:| the blame.  So there.     |

michi@ptcburp.ptcbu.oz.au (Michael Henning) (02/15/91)

burow@cernvax.cern.ch (burkhard burow) writes:

>I'm wondering if anyone has any comments on using:

>       *(a==b?&c:&d) = 1;

>instead of:

>       if (a==b) c=1;
>       else      d=1;


Yes, I do :-)

If you compare the two above statements, the answer should be obvious.
The second expression is perfectly clear and readable, whereas the first
one takes some looking at to decipher.
Besides, on many compilers, the first expression will take longer to run,
since you are dereferencing a pointer there.

							Michi.
-- 
      -m------- Michael Henning			+61 75 950255
    ---mmm----- Pyramid Technology		+61 75 522475 FAX
  -----mmmmm--- Research Park, Bond University	michi@ptcburp.ptcbu.oz.au
-------mmmmmmm- Gold Coast, Q 4229, AUSTRALIA	uunet!munnari!ptcburp.oz!michi

johnm@cory.Berkeley.EDU (John D. Mitchell) (02/15/91)

In article <16782@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com (Christopher R Volpe) writes:
>In article <11129@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John
>D. Mitchell) writes:
>|>In article <16754@crdgw1.crd.ge.com> volpe@camelback.crd.ge.com
>(Christopher R Volpe) writes:
>|>[....]
>|>>Yes, it's ugly, but it's conceivable that someone might have a good
>|>>reason for defining a macro to do this, so that the macro may be used
>|>>in an expression context.              
>|>
>|>Aahhh!  But context *is* everything.
>Huh??? So, like, what's your point?

Context:  the parts just before and after a word or passage, that
	  determines its meaning.  (Webster's New World)

In other words, the original poster gave a code snippet without any
supporting context.  That leaves the meaning up to the reader.  I for
one assumed that he was talking about using it in 'normal' code (macros
being *not* normal :-).

>|>One reason to use macros is to hide this sort of cryptic code behind
>|>a nice facade.  Oh well... if only C had...  :-)
>Isn't that what I suggested? Again, I'm unclear as to what you're trying
>to say. Are you agreeing? Disagreeing? And what is it that you wish C had?

Yep, I agree that due to whatever reasons the C language proper and its
attendant pre-processor make the expression of some kinds of functionality
cryptic, difficult, unreadable, confusing, etc.  The ternary operator
was built for its ability to be used inside the macro facility of a weak
pre-processor.  My "Oh well..." comment was a facetious attempt to jest
those who always want 'just one more feature'.

Sorry for the wasted net-width,
	John D. Mitchell
	johnm@cory.Berkeley.EDU

kers@hplb.hpl.hp.com (Chris Dollin) (02/15/91)

Someone (I've lost the attribution) asked how people felt about:

   >       *(a==b?&c:&d) = 1;
   >
   >instead of:
   >
   >       if (a==b) c=1;
   >       else      d=1;

I'll add my agreement; the first one is "Ugh". But .. how would people feel if
conditionals could deliver lvalues, ie, so that

    (a == b ? c : d) = 1;

was legal and had the obvious meaning? (Clearly, when c, d, and especially 1
are more complex expressions, you might wish to make it abundantly clear that a
*single* value was being assigned to one or other localtion.)

If anyone sees fit to respond to this, I suggest they switch newsgroups to
comp.lang.misc, as it will no longer be much to do with C ...

--

Regards, Kers.      | "You're better off  not dreaming of  the things to come;
Caravan:            | Dreams  are always ending  far too soon."

jon@maui.cs.ucla.edu (Jonathan Gingerich) (02/16/91)

burow@cernvax.cern.ch (burkhard burow) writes:
>
>   I'm wondering if anyone has any comments on using:
>
>	  *(a==b?&c:&d) = 1;
>
>   instead of:
>
>	  if (a==b) c=1;
>	  else      d=1;

Yeah, you should use meaningful names even for shortlived variables.
It seems very unlikely that a, b, c, and d would convey anything in context.

Jon.

P.S. Why not (a==b?c=1:(d=1)) ?

rh@smds.UUCP (Richard Harter) (02/16/91)

In article <15184@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
> In article <11073@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John D. Mitchell) writes:
> - In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
> - >I'm wondering if anyone has any comments on using:
> - >       *(a==b?&c:&d) = 1;
> - >instead of:
> - >       if (a==b) c=1;
> - >       else      d=1;

> My comment was going to be that it sucked bigtime.  However, I'll
> buy "ugh" as a suitable comment too.

> - P.S.	No wonder people complain about the denseness of C code!

> C code has nothing to do with it, more like the density of some coders.

But Doug, isn't it one of the unwritten rules of C coding that the
number of special characters be greater than the number of alphanumeric
characters?  :-)

Seriously, there is a germ of a good idea here.  The example is inane,
but consider

	*(a==b?&c:&d) = <some complicated messy expression>

One really doesn't want to code in said messy expression twice, so one
tends to write something like

	temp = <some complicated messy expression>
	if (a==b) c = temp;
	else      d = temp;

Again this is more readable (and mainatainable).  However the ugly one
liner is better code in the sense of not having replications of a single
term or in using temporaries.

To be honest this is a trick I would have never thought of and would never
use in C.  In principle the idea is a good one but the C conditional
expression is just too darned ugly.
-- 
Richard Harter, Software Maintenance and Development Systems, Inc.
Net address: jjmhome!smds!rh Phone: 508-369-7398 
US Mail: SMDS Inc., PO Box 555, Concord MA 01742
This sentence no verb.  This sentence short.  This signature done.

throopw@sheol.UUCP (Wayne Throop) (02/16/91)

- gwyn@smoke.brl.mil (Doug Gwyn)
-- rh@smds.UUCP (Richard Harter)

-- [.. some context restored ..]
--       *(a==b?&c:&d) = <some complicated messy expression>
-- However the ugly one liner is better code in the sense of not having
-- replications of a single term or in using temporaries.  [...] In
-- principle the idea is a good one but the C conditional expression is
-- just too darned ugly. 
- There are good ways of exploiting the ?: operator and bad ways.
- The example being discussed is clearly among the latter.

I'm not sure I understand.  Could either Doug or Richard expand a little
on just why the expression is "ugly" or a "bad way" to exploit the
conditional operator?  It doesn't seem any worse than, say

         foo[a==b?c:d] = something;

or even just

         foo[(a+b)*(c+d)] = something;

or the like.  All are examples of a complicated decision going into
exactly which object is going to be assigned to.  Granted, the
conditional is more extreme than the subscripting examples, but not to
any large degree IMHO.  So why is the explicit conditional any worse
than the others?

( Note: the restored context above may have obliterated the "example
        being discussed" by Doug.  If the example I left there isn't
        the one he means, forgive me. )
--
Wayne Throop <backbone>!mcnc!rti!sheol!throopw or sheol!throopw@rti.rti.org

dcl@ncsc1.ATT.COM (Dave Love) (02/17/91)

In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>I'm wondering if anyone has any comments on using:
>       *(a==b?&c:&d) = 1;

Fine.

As long as I never have to maintain your code. 

>thanks, burkhard  burow%13313.hepnet@csa3.lbl.gov


-- 
 Dave Love  
 UUCP: dcl@ncsc1.att.com  CI$: 75126,2223   bix: dlove  

 -- "MS-DOS... The ultimate PC virus." --

gwyn@smoke.brl.mil (Doug Gwyn) (02/17/91)

In article <326@smds.UUCP> rh@smds.UUCP (Richard Harter) writes:
>> - >       *(a==b?&c:&d) = 1;
>Seriously, there is a germ of a good idea here.

There are good ways of exploiting the ?: operator and bad ways.
The example being discussed is clearly among the latter.

steve@taumet.com (Stephen Clamage) (02/17/91)

kers@hplb.hpl.hp.com (Chris Dollin) writes:

>.. how would people feel if conditionals could deliver lvalues, ie, so that
>    (a == b ? c : d) = 1;
>was legal and had the obvious meaning?

As has been pointed out before, this is an extension to Gnu C.

The expression is also legal C++, as long as c and d are both lvalues
and have the same type (although not all compilers yet implement this
feature).
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

gwyn@smoke.brl.mil (Doug Gwyn) (02/18/91)

In article <1196@sheol.UUCP> throopw@sheol.UUCP (Wayne Throop) writes:
>-- [.. some context restored ..]
>--       *(a==b?&c:&d) = <some complicated messy expression>
>- There are good ways of exploiting the ?: operator and bad ways.
>- The example being discussed is clearly among the latter.
>I'm not sure I understand.  Could either Doug or Richard expand a little
>on just why the expression is "ugly" or a "bad way" to exploit the
>conditional operator?

You mis-restored the context.  The original example did NOT assign
the value of "some complicated messy expression"; rather, it assigned
the integer constant 1.  It is an abuse of the potential utility of
the ?: operator to use it, especially with the addition of levels of
indirection, where a simple
	if ( a == b )
		c = 1;
	else
		d = 1;
would be much clearer and (assuming a decent compiler) at least as
efficient.  I doubt that efficiency should have been an issue anyway;
however, clarity is very important.  If you doubt that, some remedial
reading of software engineering classics is indicated.

throopw@sheol.UUCP (Wayne Throop) (02/18/91)

> brnstnd@kramden.acf.nyu.edu (Dan Bernstein)
> I'd write [..multi-line if statements instead of
>              cryptic one-liners involving ?: ..]

So would I, 99 and 44 one-hundreths percent of the time.

And the remaining .56 percent of the time wouldn't be for reasons
of "efficency" or to "get close to the machine" or any such secondary
goal.  As Dan points out, such things are unlikely to win over the
good ol' if-then-else.

And yet...  every now and then, one naturally thinks of a situation as
assigning (or incrementing, or tweaking, or whatever) "the appropriate
one of" a set of lvalues.  Now, most often this is modeled as assignment
to an array.  But every once in a blue moon, the lvalues are not related
by membership in an array, nor by anything much in particular beyond
their participation in being one of the set of "appropriate ones" to
assign something to. 

In such a rare case, I'd 'druther code the way I think about it,
and think about it the way I code it.... that is, I'd really rather
model it as a single assignment to a peculiar lvalue.

So while I tend to agree that ?: in lhs expressions are, as a
statistical tendency, an abomination, I can't agree that this
is because of anything wrong with the idea in itself... just
that the application's rightful place is very rare.

The moral is (again): code like you think, think like you code.
( I hope this moral is thought provoking but essentially
  uncontroversial, but one never knows...  )
--
Wayne Throop <backbone>!mcnc!rti!sheol!throopw or sheol!throopw@rti.rti.org

throopw@sheol.UUCP (Wayne Throop) (02/18/91)

> rh@smds.UUCP (Richard Harter)

[.. discussing assignment to expressions like *(a==b?&c:&d) ..]
> First of all the trick of using
> *(cond?&var1:&var2) is not technically legal since the result of the
> ?: is not an lvalue.  [Harbison & Steele].  I rather suspect you could
> sneak it past most compilers though.

Well... I'd say "all correct C compilers" really ought to be "most",
wouldn't you?

As Dan Bernstein has pointed out in another article, Richard is
incorrect here.  While it is true that the result of ?: is never
an lvalue, this is irrelevant since the result of * always is.	

> Secondly the syntax of the condition is, in its own right, ugly.

No uglier than much else of C's alphabet soup operators, I'd say.

> Thirdly, the use of the conditional in an lvalue obscures the destination
> of an assignment.

I agree, but this is appropriate if the destination is, in fact,
obscure or arcane.  That is, I agree it is something to be avoided,
but I think it may sometimes be the least of the available evils.

> Fourthly, the ?: is hard to read (see second complaint above).

Again, I agree with the same reservation as in "thirdly" above.

> Fifthly, the original example is an instance of making code less efficient
> in the process of reducing the number of statements since you have to
> reference and dereference.

It's a pretty poor compiler that would be confused by this into
doing something noticeably inefficent.

On the other hand, I think it is Morally Wrong to invoke extraneous
operations.  (And even if I'm a little vague on what can be classed
as extraneous, I would be perverse not to include the address-of
operation in the example under discussion as extraneous.)


Keep in mind: I agree that ?: is not well suited for the LHS
of expressions... I was just overreacting to what I perceived
as an oversimple blanket condemnation.  (Before chastizing me
on grounds that this is all in my mind, realize that I KNOW that...
but taking what has been said as a blanket condemnation is an
error worth warning folks against, isn't it?  Well... isn't it?)
--
Wayne Throop <backbone>!mcnc!rti!sheol!throopw or sheol!throopw@rti.rti.org

rh@smds.UUCP (Richard Harter) (02/18/91)

In article <15227@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
> In article <326@smds.UUCP> rh@smds.UUCP (Richard Harter) writes:
> >> - >       *(a==b?&c:&d) = 1;
> >Seriously, there is a germ of a good idea here.

> There are good ways of exploiting the ?: operator and bad ways.
> The example being discussed is clearly among the latter.

I agree that the example is a bad idea -- of using the ?: operator
in C.  For that matter the ?: operator is one of the uglier things in
C.  What the chap was doing was emulating a feature that is not in C
or in most other languages, i.e. selected assignment.  The idea is
interesting although I am not sure it is worthwhile.  For example you
can do something like this is in C:

static int a,b,c,d;
static int *index[4] = {&a,&b,&c,&d};
	....
	*index[i] = some-expression;

which is a round-about way of saying "set the i'th item in the list
a,b,c,d to 'some-expression'".  The point is that the example is an
attempt to do something which C does not provide a natural way of doing.
-- 
Richard Harter, Software Maintenance and Development Systems, Inc.
Net address: jjmhome!smds!rh Phone: 508-369-7398 
US Mail: SMDS Inc., PO Box 555, Concord MA 01742
This sentence no verb.  This sentence short.  This signature done.

rh@smds.UUCP (Richard Harter) (02/18/91)

In article <1196@sheol.UUCP>, throopw@sheol.UUCP (Wayne Throop) writes:
> - gwyn@smoke.brl.mil (Doug Gwyn)
> -- rh@smds.UUCP (Richard Harter)
> 
> -- [.. some context restored ..]
> --       *(a==b?&c:&d) = <some complicated messy expression>
> -- However the ugly one liner is better code in the sense of not having
> -- replications of a single term or in using temporaries.  [...] In
> -- principle the idea is a good one but the C conditional expression is
> -- just too darned ugly. 
> - There are good ways of exploiting the ?: operator and bad ways.
> - The example being discussed is clearly among the latter.

As Doug points out in another message the original had 1. instead of
a complex expression.  

> I'm not sure I understand.  Could either Doug or Richard expand a little
> on just why the expression is "ugly" or a "bad way" to exploit the
> conditional operator?  It doesn't seem any worse than, say

>          foo[a==b?c:d] = something;

> or even just

>          foo[(a+b)*(c+d)] = something;

> or the like.  All are examples of a complicated decision going into
> exactly which object is going to be assigned to.  Granted, the
> conditional is more extreme than the subscripting examples, but not to
> any large degree IMHO.  So why is the explicit conditional any worse
> than the others?

Let's run down the line on this.  First of all the trick of using
*(cond?&var1:&var2) is not technically legal since the result of the
?: is not an lvalue.  [Harbison & Steele].  I rather suspect you could
sneak it past most compilers though.   However by doing so you are are
violating the specs and the intent of the language [for what that's
worth.]

Secondly the syntax of the condition is, in its own right, ugly.  This
is a personal opinion, but it is seconded by some noted practioners of
the art.  Why is it ugly?  It is ugly because it has special rules and
syntax that do not fit the rest of the language.  C is (despite the
complaints) actually a fairly elegant and well designed language.  The
syntax is quite regular.  The conditional uses special symbols in a way
that is not very consistent with the rest of the language.  Call this
an esthetic objection if you like.

Thirdly, the use of the conditional in an lvalue obscures the destination
of an assignment.  This is equally true whether you write

	*(a==b?&x:&y) = expression;  /* ugh */
or	f[a==b?i:j]   = expression;  /* not quite as bad */

If you are reading the code it is less than obvious what is being set.

Fourthly, the ?: is hard to read (see second complaint above).  It is
particularly hard to read when it is used as a sub expression.  Let me
give an example, with apologies to Rich Salz:

	/* This next line requires a good C compiler. */
	if (*p == '-' ? *text <= *++p && *text >= last : *text == *p)
	    matched = TRUE;

Fifthly, the original example is an instance of making code less efficient
in the process of reducing the number of statements since you have to
reference and dereference.  In the old days beginning programmers had
to learn the hard way that clever tricks to reduce the number of lines
of code often lead to code that took longer to execute.

Having said all these nasty things, are there any reasons why one would
use the conditional?  One can do without it -- I wrote C for five years
before I used my first conditional.  One reason, which several people
have mentioned, is that it facilitates macro writing.  Another is that
it does, in fact, solve a real problem.  There really is a need for
conditional expressions.
-- 
Richard Harter, Software Maintenance and Development Systems, Inc.
Net address: jjmhome!smds!rh Phone: 508-369-7398 
US Mail: SMDS Inc., PO Box 555, Concord MA 01742
This sentence no verb.  This sentence short.  This signature done.

hugh@fivegl.co.nz (Hugh Grierson) (02/18/91)

In article <1991Feb13.223412.28254@grebyn.com> ckp@grebyn.com (Checkpoint Technologies) writes:
>In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>>I'm wondering if anyone has any comments on using:
>>
>>       *(a==b?&c:&d) = 1;

[general Ugh comments...]

>The only time I would use the first form is in a macro, in a situation
>where I really wanted an expression rather than a statement.  But that's
>all.

Even then it would be better to use...

#define cord(a,b,c,d) (a==b?c=1:d=1)

-- 
Hugh Grierson     hugh@fivegl.co.nz | Perfection is attained not when there is
5GL International Ltd,              | no more that can be added, but when there
Auckland, New Zealand               | is no more that can be taken away.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (02/18/91)

In article <331@smds.UUCP> rh@smds.UUCP (Richard Harter) writes:
> Let's run down the line on this.  First of all the trick of using
> *(cond?&var1:&var2) is not technically legal since the result of the
> ?: is not an lvalue.

Say what? It doesn't matter whether foobiebletch is an lvalue as long as
nobody tries to assign a value to it. Here foobiebletch is a (non-const)
pointer type, so *foobiebletch is an lvalue, and *foobiebletch = x is
fine.

> Secondly the syntax of the condition is, in its own right, ugly.

Yes. I'd write either

 {
  register glorp *addr;
  if (cond) addr = &var1;
  else      addr = &var2;
  *addr = expr;
 }

or

 {
  register glorp temp;
  temp = expr;
  if (cond) var1 = temp;
  else      var2 = temp;
 }

if any of the expressions involved were particularly complex. How else
would the machine do the job anyway?

> There really is a need for
> conditional expressions.

This can be argued. ?: is almost purely syntactic; I don't know any
machine that will optimize a ?: expression better than an equivalent
if-then. Its syntactic benefits are minimal at best.

---Dan

throop@aurs01.UUCP (Wayne Throop) (02/19/91)

>  gwyn@smoke.brl.mil (Doug Gwyn)

[.. discussing *(a==b?&c:&d) = 1 ..]
> It is an abuse of the potential utility of the ?: operator to use it,
> especially with the addition of levels of indirection, where a simple
>            if ( a == b ) c = 1; else d = 1;
> would be much clearer [...] clarity is very important.

I agree strongly about the general principle of clarity.  But I suspect
I may differ in the question of what is clear.  To start with
agreement, I agree about the extra levels of indirection being
unclear.  For example,

       *(color==BLUE? &blue_items : &nonblue_items) += 1;

is more messy (and less to be prefered) than

       if( color==BLUE )
           blue_items += 1;
       else
           nonblue_items += 1;

Worse still, the former requires mumble_items to be addressable, when
they conceptually only need to be lvalues.

But on the other hand, I'd say that the GCC extension

        (color==BLUE ? blue_items : nonblue_items) += 1;

is clearer than either, and something like

        *(color==BLUE ? blue_items_ref : nonblue_items_ref) += 1;

seems perfectly clear to me, and (as a matter of taste) preferable to
the use of an "if" statement (say, inside a routine which counts item
colors as a side effect and is passed references to counts to fill in
(uh... not that I'd tend to design a routine that way, but supposing
someone did...)).

Certainly (hmmm... better say "IMHO"), it isn't much less clear than

          item_count[color] += 1;

Wayne Throop       ...!mcnc!aurgate!throop

gwyn@smoke.brl.mil (Doug Gwyn) (02/19/91)

In article <5672:Feb1814:26:0291@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>> There really is a need for
>> conditional expressions.
>This can be argued. ?: is almost purely syntactic; ...

Yes, but then so is the provision of a multiplicity of ways of
expressing looping.  I seldom have occasion to assign the same value
to alternative variables, as in the example that started this thread,
but often I need to assign alternative values to a given variable, or
return alternative values from a function.  Often it is both
convenient and clear to use a ?: expression rather than cast the code
into the form of an "if" statement.

drd@siia.mv.com (David Dick) (02/20/91)

In <326@smds.UUCP> rh@smds.UUCP (Richard Harter) writes:

>In article <15184@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
>> In article <11073@pasteur.Berkeley.EDU>, johnm@cory.Berkeley.EDU (John D. Mitchell) writes:
>> - In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>> - >I'm wondering if anyone has any comments on using:
>> - >       *(a==b?&c:&d) = 1;
>> - >instead of:
>> - >       if (a==b) c=1;
>> - >       else      d=1;

>Seriously, there is a germ of a good idea here.  The example is inane,
>but consider

>	*(a==b?&c:&d) = <some complicated messy expression>

>One really doesn't want to code in said messy expression twice, so one
>tends to write something like

>	temp = <some complicated messy expression>
>	if (a==b) c = temp;
>	else      d = temp;

I believe that the result of a conditional expression 
is explicitly defined to be an r-value, so that
it cannot be assigned into.

David Dick
Software Innovations, Inc. [the Software Moving Company(sm)]

michi@ptcburp.ptcbu.oz.au (Michael Henning) (02/20/91)

throopw@sheol.UUCP (Wayne Throop) writes:

>As Dan Bernstein has pointed out in another article, Richard is
>incorrect here.  While it is true that the result of ?: is never
>an lvalue, this is irrelevant since the result of * always is.	
                                         ^^^^^^^^^^^^^^^^^^^^^

Hmmm...

What about

int	array[10][10];

and an expression

	*array

The type of the expression after dereferencing is "array of 10 ints", which
is *not* an lvalue.


							Michi.
-- 
      -m------- Michael Henning			+61 75 950255
    ---mmm----- Pyramid Technology		+61 75 522475 FAX
  -----mmmmm--- Research Park, Bond University	michi@ptcburp.ptcbu.oz.au
-------mmmmmmm- Gold Coast, Q 4229, AUSTRALIA	uunet!munnari!ptcburp.oz!michi

gwyn@smoke.brl.mil (Doug Gwyn) (02/20/91)

In article <59582@aurs01.UUCP> throop@aurs01.UUCP (Wayne Throop) writes:
>>  gwyn@smoke.brl.mil (Doug Gwyn)
>>            if ( a == b ) c = 1; else d = 1;

Actually I would never recommend the one-line format that you compressed
this to.

torek@elf.ee.lbl.gov (Chris Torek) (02/20/91)

>throopw@sheol.UUCP (Wayne Throop) writes:
[the result of unary `*' (indirect) is always an lvalue]

In article <335@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au
(Michael Henning) writes [abbreviated]:
>	int	array[10][10];
>	*array
>The type of the expression after dereferencing is "array of 10 ints", which
>is *not* an lvalue.

Technically, the result *is* an lvalue (according to ANSI terminology,
at least)---but it is not a `modifiable' lvalue.

(The type of `array' above is `array 10 of array 10 of int'; in a value
context, such as the target of unary `*', this changes to `pointer to
array 10 of int'.  The indirection changes this it `array 10 of int',
which, in an expression context, devolves to `pointer to int'.  Until
the final devolving, however, the object produced by the indirection is
a non-modifiable lvalue of type `array 10 of int'.)
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

sarima@tdatirv.UUCP (Stanley Friesen) (02/21/91)

In article <335@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes:
>throopw@sheol.UUCP (Wayne Throop) writes:
>> this is irrelevant since the result of * always is [an lvalue].
                                          ^^^^^^^^^^^^^^^^^^^^^
>What about
 
>int	array[10][10];
 
>and an expression
 
>	*array
 
>The type of the expression after dereferencing is "array of 10 ints", which
>is *not* an lvalue.

Yes it is, at least according to the ANSI definition of lvalue.  It is just
not a *modifiable* lvalue.  [Of course this is 'promoted' to a pointer to int
in most contexts].
In fact the ANSI standard explicitely states that the result of the unary *
operator is an lvalue (with *no* conditions).
-- 
---------------
uunet!tdatirv!sarima				(Stanley Friesen)

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (02/21/91)

In article <335@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes:
> int	array[10][10];
> 	*array
> The type of the expression after dereferencing is "array of 10 ints", which
> is *not* an lvalue.

Either (1) array types are never lvalues, or (2) array types can never
be assigned to even if they are lvalues. I don't know which way the
standard defines lvalues; I find (2) a simpler approach, but in any case
(1) and (2) produce the same results.

None of this is relevant to the question at hand, which is whether

  *(cond ? &a : &b) = x

is valid. It is, provided that a = x and b = x are valid. It will work
under any sane compiler. It must work under an ANSI compiler.

---Dan

al@unhd.unh.edu (Anthony Lapadula) (02/21/91)

In article <5669:Feb2020:23:4791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>
>None of this is relevant to the question at hand, which is whether
>
>  *(cond ? &a : &b) = x
>
>is valid. It is, provided that a = x and b = x are valid. It will work
>under any sane compiler. It must work under an ANSI compiler.

Not true.  Consider

	int a;
	char b;
	int x;

Certainly ``a = x'' and ``b = x'' are valid, but ``*(cond ? &a : &b) = x''
is not.

-- Anthony (uunet!unhd!al, al@cs.unh.edu) Lapadula

"I would agree with you if you were right."  --  Dr Sayer, "Awakenings"

michi@ptcburp.ptcbu.oz.au (Michael Henning) (02/21/91)

torek@elf.ee.lbl.gov (Chris Torek) writes:

>>throopw@sheol.UUCP (Wayne Throop) writes:
>[the result of unary `*' (indirect) is always an lvalue]

>In article <335@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au
>(Michael Henning) writes [abbreviated]:
>>	int	array[10][10];
>>	*array
>>The type of the expression after dereferencing is "array of 10 ints", which
>>is *not* an lvalue.

>Technically, the result *is* an lvalue (according to ANSI terminology,
>at least)---but it is not a `modifiable' lvalue.

>(The type of `array' above is `array 10 of array 10 of int'; in a value
>context, such as the target of unary `*', this changes to `pointer to
>array 10 of int'.  The indirection changes this it `array 10 of int',
>which, in an expression context, devolves to `pointer to int'.  Until
>the final devolving, however, the object produced by the indirection is
>a non-modifiable lvalue of type `array 10 of int'.)

Hmmm..., I'm confused now. From K & R:

"An *object* is a manipulatable region of storage; an *lvalue* is an expression
referring to an object.  [...]  There are operators which yield lvalues:
for example, if E is an expression of pointer type, then *E is an lvalue
expression referring to the object to which E points. The name "lvalue"
comes from the assignment expression E1 = E2 in which the left operand E1
must be an lvalue expression."

And further on, in the section about the * operator:

"The unary * operator means indirection: the expression must be a pointer,
and the result is an lvalue referring to the object to which the expression
points. If the type of the expression is "pointer to ...", the type of the
result is "..."."

And in the section about the various assignment operators:

"  [...]  All require an lvalue as their left operand, and the type of an
assignment expression is that of its left operand.  [...]  "


From Harbison & Steele:

"An "lvalue" is an expression that refers to an object in such a way that the
object may be altered as well as examined.  [...]  (An expression or result is
called an lvalue because it may be used on the left-hand side of an
assignment.  [...]  )

  [...]

An indirection expression *e is always an lvalue, regardless of whether e
is an lvalue."


Neither K & R nor Harbison & Steele make any distinction between modifiable
and non-modifiable lvalues. Furthermore, both say that the result of
applying a dereference operator to a pointer *always* yields an lvalue,
and that the left operand of an assignment operator must be an lvalue.
Yet, if "array" is a two dimensional array, then "*array", by definition, is
an lvalue, but "*array" cannot appear on the left hand side of an assignment
statement, since the usual unary conversions (conversion to a pointer in this
case) do not take place for the left operand, and the type of the left
operand is "array of 10 ints".

I get the impression that there simply are some inconsistencies in the
language definition. Either an object is an lvalue, in which case it can
be used as the left operand of an assignment, or it isn't, in which case
it cannot be used that way. I believe that the issue could be cleaned up
by changing the definition of "*" to say something like

The unary operator means indirection: the expression must be a pointer, and
the result is an lvalue referring to the object to which the expression points,
except if the object is an array.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Something to that effect should clean things up. Any comments anyone ?

							Michi.
-- 
      -m------- Michael Henning			+61 75 950255
    ---mmm----- Pyramid Technology		+61 75 522475 FAX
  -----mmmmm--- Research Park, Bond University	michi@ptcburp.ptcbu.oz.au
-------mmmmmmm- Gold Coast, Q 4229, AUSTRALIA	uunet!munnari!ptcburp.oz!michi

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (02/21/91)

In article <1991Feb20.215402.16343@unhd.unh.edu> al@unhd.unh.edu (Anthony Lapadula) writes:
> In article <5669:Feb2020:23:4791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >None of this is relevant to the question at hand, which is whether
> >  *(cond ? &a : &b) = x
> >is valid. It is, provided that a = x and b = x are valid. It will work
> >under any sane compiler. It must work under an ANSI compiler.
> Not true.

Oops, sorry. Make that ``a and b have the same type and a = x is valid.''

---Dan

torek@elf.ee.lbl.gov (Chris Torek) (02/21/91)

>>In article <335@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au
>>(Michael Henning) writes [abbreviated]:
>>>	int	array[10][10];
>>>	*array
>>>The type of the expression after dereferencing is "array of 10 ints", which
>>>is *not* an lvalue.

>In article <10069@dog.ee.lbl.gov> I wrote:
>>Technically, the result *is* an lvalue (according to ANSI terminology,
>>at least)---but it is not a `modifiable' lvalue.

In article <337@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au
(Michael Henning) writes:
>Hmmm..., I'm confused now. [quotes K&R and H&S]
>Neither K & R nor Harbison & Steele make any distinction between modifiable
>and non-modifiable lvalues.

Two points:

	a) both K&R and H&S exist in multiple editions (and K&R 2, at
	   least, exists in several versions; later printings have some
	   minor fixes).
	b) Neither K&R nor H&S claim to be the ANSI C standard.  For
	   that you must obtain X3.159-1989 from your local ANSI distributor.

The introduction of `modifiable' and `nonmodifiable' lvalues is new in
ANSI C; something like it is needed to make sense of `const int x = 3',
in which x is an lvalue but may not be assigned-to.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

sarima@tdatirv.UUCP (Stanley Friesen) (02/22/91)

In article <337@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes:
|Hmmm..., I'm confused now. From K & R:
|
|"An *object* is a manipulatable region of storage; an *lvalue* is an expression
|referring to an object.  [...] ...

|From Harbison & Steele:
|
|"An "lvalue" is an expression that refers to an object in such a way that the
|object may be altered as well as examined.  [...] ...

Note that these definitions are *different*.  The K&R definition does *not*
imply that an lvalue may be used on the left hand side of an assignment.

|Neither K & R nor Harbison & Steele make any distinction between modifiable
|and non-modifiable lvalues. Furthermore, both say that the result of
|applying a dereference operator to a pointer *always* yields an lvalue,
|and that the left operand of an assignment operator must be an lvalue.
|Yet, if "array" is a two dimensional array, then "*array", by definition, is
|an lvalue, but "*array" cannot appear on the left hand side of an assignment
|statement, since the usual unary conversions (conversion to a pointer in this
|case) do not take place for the left operand, and the type of the left
|operand is "array of 10 ints".
|I get the impression that there simply are some inconsistencies in the
|language definition.

Quite correct.  The definitions and constraints as presented in the non-ANSI
texts are *inconsistant*!   This is why the ANSI committee decided to clarify
the matter.  They chose to use the K&R definition of lvalue, and to revise the
constraint on assignment operators to require a *modifiable* lvalue as the
left operand.  They chose this approach largely because it simplified the
semantics of the 'const' qualifier - a 'const' expression can simply be
described as one that refers to an object that cannot be modified.  Now
both the restriction against assignment to arrays and the proper restrictions
on the use of 'const' entities are captured in a single constraint on
assignments and a single definition (of 'modifiable lvalue').  This also
allowed the C standard to retain the simple rule that a dereference *always*
yields an lvalue.

|Either an object is an lvalue, in which case it can
|be used as the left operand of an assignment, or it isn't, in which case
|it cannot be used that way. I believe that the issue could be cleaned up
|by changing the definition of "*" to say something like ...
 
|Something to that effect should clean things up. Any comments anyone ?

Except that the ANSI committee has already cleaned things up the other way,
and with less complexity - since non-modifiable lvalues are the best way
to handle 'const' anyway.  [Trying to say that a 'const' variable does
not yield an lvalue leads to a very complex definition for lvalue].
-- 
---------------
uunet!tdatirv!sarima				(Stanley Friesen)

gwyn@smoke.brl.mil (Doug Gwyn) (02/22/91)

In article <337@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes:
>Something to that effect should clean things up. Any comments anyone ?

Yeah -- get hold of a copy of the C standard, which has already
straightened this matter out.

s900387@minyos.xx.rmit.oz.au (Craig Macbride) (02/23/91)

johnm@cory.Berkeley.EDU (John D. Mitchell) writes:

>In article <4155@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>>I'm wondering if anyone has any comments on using:
>>       *(a==b?&c:&d) = 1;
>>instead of:
>>       if (a==b) c=1;
>>       else      d=1;

>1) Readability, readability, READABILITY!

>2) Why?  It's not any faster.

3) If someone decides to make c and/or d register variables, they have to
decipher and change your cryptic piece of assignment code.

-- 
 _____________________________________________________________________________
| Craig Macbride, s900387@minyos.xx.rmit.oz.au |  Reality is for people who   |
| Only the equipment belongs to Victoria Uni.  | can't handle science fiction.|
| of Technology (RMIT); The opinions are mine. |______________________________|

rh@smds.UUCP (Richard Harter) (02/23/91)

In article <1210@sheol.UUCP>, throopw@sheol.UUCP (Wayne Throop) writes:
> > rh@smds.UUCP (Richard Harter)

> [.. discussing assignment to expressions like *(a==b?&c:&d) ..]
> > First of all the trick of using
> > *(cond?&var1:&var2) is not technically legal since the result of the
> > ?: is not an lvalue.  [Harbison & Steele].  I rather suspect you could
> > sneak it past most compilers though.

> As Dan Bernstein has pointed out in another article, Richard is
> incorrect here.  While it is true that the result of ?: is never
> an lvalue, this is irrelevant since the result of * always is.	

Mea culpa, remove foot from mouth, etc.  Actually, as other articles
have pointed out there are some fine points, depending on whether you
are talking about paleolithic C, neo-modern classic C, or ANSI C.
However the cited remark was a bit of all wrong.

As far as the ?: syntax is concerned I would like to reiterate the point
that it is dissimilar to other C constructs (other than that it uses still
more special symbols.)  All other operators which use punctuation (with
the exception of ->) are either unary or binary operators.  All conditional
operations, except for ?:, use words, e.g. if, else, while, etc.  It is
a wart.
-- 
Richard Harter, Software Maintenance and Development Systems, Inc.
Net address: jjmhome!smds!rh Phone: 508-369-7398 
US Mail: SMDS Inc., PO Box 555, Concord MA 01742
This sentence no verb.  This sentence short.  This signature done.