Side effects in conditional expressions

  • Thread starter August Karlstrom
  • Start date
A

August Karlstrom

Among C programmers it is not uncommon to use expressions with
side-effects such as `y++' in the statement `x = y++;'. If we look at a
statement like

(x == 0)? x++: y *= 2;

Would this be considered bad coding style? Motivate your answer.


/August
 
C

Chïna Blüe Öyster Cult

August Karlstrom said:
(x == 0)? x++: y *= 2;

Would this be considered bad coding style? Motivate your answer.

Can you guarentee what will be assigned to what if x==0 or x==1? If not, you
have been answered.

Also x++ is a rvalue, not an lvalue, so even if ?: has been extended to lvalues,
this won't work.
 
A

August Karlstrom

Can you guarentee what will be assigned to what if x==0 or x==1? If not, you
have been answered.

Also x++ is a rvalue, not an lvalue, so even if ?: has been extended to lvalues,
this won't work.

OK, I apparently need parentheses around `y *= 2' so it should read

(x == 0)? x++: (y *= 2);


/August
 
L

lawrence.jones

August Karlstrom said:
It should be

(x == 0)? x++: (y *= 2);

No, it should be

if (x == 0) x++;
else y *= 2;

It is considered very poor style to use ?: and ignore the result -- an
if statment is clearer and avoids the precedence issues.
 
M

Mr. Buffoon

Am 01.10.2010 23:38, schrieb August Karlstrom:
Among C programmers it is not uncommon to use expressions
with side-effects such as `y++' in the statement `x = y++;'.
If we look at a statement like
(x == 0)? x++: y *= 2;
Would this be considered bad coding style? Motivate your answer.

Change to a compiler which automatically fixes your buggy code!
 
A

August Karlstrom

No, it should be

if (x == 0) x++;
else y *= 2;

It is considered very poor style to use ?: and ignore the result -- an
if statment is clearer and avoids the precedence issues.

OK, let's change it to

z = (x == 0)? x++: (y *= 2);

then.

Note that I would never write this kind of code myself. I wouldn't even
write `x = y++;' but `x = y; y++;'. What I'm trying to find out is
whether there is some common acceptance level among seasoned C
programmers of how convoluted the code is allowed to be.


/August
 
E

Edward

August said:
Among C programmers it is not uncommon to use expressions with
side-effects such as `y++' in the statement `x = y++;'. If we look at a
statement like

(x == 0)? x++: y *= 2;

Would this be considered bad coding style? Motivate your answer.


/August
It depends. If you're entering the IOCCC, it's acceptable if a little
too readable. Anywhere else, it's asking for trouble. The harder you
have to work to understand the code, the more likely subtle bugs are to
get past you - as with the precedence problem in your above code that
other posters have identified.
-Edward
 
K

Kenny McCormack

August Karlstrom said:
Note that I would never write this kind of code myself. I wouldn't even
write `x = y++;' but `x = y; y++;'. What I'm trying to find out is
whether there is some common acceptance level among seasoned C
programmers of how convoluted the code is allowed to be.

All you're going to get here is "Don't do that!"
 
A

August Karlstrom

It depends. If you're entering the IOCCC, it's acceptable if a little
too readable. Anywhere else, it's asking for trouble. The harder you
have to work to understand the code, the more likely subtle bugs are to
get past you

Exactly. As I have already mentioned in this thread I wouldn't write
this kind of code myself. Would you also reject the string copy idiom

while (*t++ = *s++);

with the same motivation?


/August
 
B

Ben Bacarisse

August Karlstrom said:
OK, let's change it to

z = (x == 0)? x++: (y *= 2);

then.

Note that I would never write this kind of code myself. I wouldn't
even write `x = y++;' but `x = y; y++;'. What I'm trying to find out
is whether there is some common acceptance level among seasoned C
programmers of how convoluted the code is allowed to be.

One reason there have not been many answers could be that the answer
probably depends on the context and the exact details of the
expressions. I don't have a built-in aversion to side effects in the
arms of a conditional, but I am having trouble thinking of an example
where the rather wild pattern you quote is the best way to write
something specific.

The best I've been able to come up with is merging two arrays into one
where it might be reasonable (depending on the termination condition) to
write the core of the loop as:

m[i++] = a[j] < b[k] ? a[j++] : b[k++];

but here the side effects are not as bizarrely unrelated as x++ and y *=
2 and that symmetry makes it seem quite reasonable to me.
 
E

Edward

August said:
Exactly. As I have already mentioned in this thread I wouldn't write
this kind of code myself. Would you also reject the string copy idiom

while (*t++ = *s++);

with the same motivation?


/August
No, I think that's reasonable (essentially it's describing an LDCPIR,
which one would hope the compiler would be clever enough to optimise it
into), except that if using the result of an assignment as a condition
you should enclose in an extra set of brackets. Typically your compiler
should warn you otherwise (as you might have meant == instead). Of
course, unless you want to compare to something other than zero,
string.h's strcpy() would be more appropriate.
The interesting one, though, is if you want to copy within an array,
perhaps even copying between regions which overlap - since then you need
to be able to choose whether it LDIRs or LDDRs. In that case you might
have something like
while(i++,a[i-1]=a);
to shift down, but
while(a=a[i-1],i--);
to shift up (of course you'd have to initialise i appropriately).
You have to be careful, though, not to invoke UB with something like
that (hence why I've used separate comma expressions to inc/dec i).
-Edward
 
L

lawrence.jones

August Karlstrom said:
Note that I would never write this kind of code myself. I wouldn't even
write `x = y++;' but `x = y; y++;'. What I'm trying to find out is
whether there is some common acceptance level among seasoned C
programmers of how convoluted the code is allowed to be.

It's allowed to be as convoluted as it needs to be, but no more. :)
 
F

FredK

Note that I would never write this kind of code myself. I wouldn't even
write `x = y++;' but `x = y; y++;'. What I'm trying to find out is whether
there is some common acceptance level among seasoned C programmers of how
convoluted the code is allowed to be.

Frankly, I almost never use ++ or -- unless I'm operating on a pointer. x
+= 1; is much clearer and generates the same code as x++; if what you really
are doing is incrementing by 1.

Saving a line of source generally doesn't make the generated code any
better/faster and can make the code less obvious.
 
A

August Karlstrom

That is ridiculous.

More statements.

But less subtlety and in my opinion a cleaner (de)composition of side
effects.
If ANY C programmer doesnt understand "x=y++;" he has no right to be a C
programmer.

If I saw your way my first reaction would "uh oh, a total C amateur, I
wonder what else is screwed up because he cant cope with the language
constructs"?

C gives you the freedom to be non-terse as well.
x=y++ is not convoluted. It's a basic of C.

These kind of shortcuts make it elegant.

Beauty is in the eye of the beholder.


/August
 
A

August Karlstrom

Frankly, I almost never use ++ or -- unless I'm operating on a pointer. x
+= 1; is much clearer and generates the same code as x++; if what you really
are doing is incrementing by 1.

My point is not so much about the syntax. I'm fine with ++ but the
"problem" in my opinion is when its value is used.
Saving a line of source generally doesn't make the generated code any
better/faster and can make the code less obvious.

Agreed. To me being able to read the meaning of a statement aloud is a
necessary condition of clarity.


/August
 
K

Keith Thompson

FredK said:
Frankly, I almost never use ++ or -- unless I'm operating on
a pointer. x += 1; is much clearer and generates the same code
as x++; if what you really are doing is incrementing by 1.

Really? I find "x++" clearer than "x += 1"; if I see the latter,
I'm just going to wonder why the author didn't use "x++".

And why don't use "x += 1" for pointers?
Saving a line of source generally doesn't make the generated code any
better/faster and can make the code less obvious.

"x++" doesn't save a line of source. It's just clearer to most
experienced C programmers.
 
A

August Karlstrom

August said:
Would you also reject the string copy idiom

while (*t++ = *s++);

with the same motivation?
[...]
if using the result of an assignment as a condition
you should enclose in an extra set of brackets. Typically your compiler
should warn you otherwise (as you might have meant == instead).

Why should we as C programmers allow ourselves to be dumbed down by the
compiler? We know what we're doing, right? (Just trying a different
standpoint.)
Of course, unless you want to compare to something other than zero,
string.h's strcpy() would be more appropriate.
The interesting one, though, is if you want to copy within an array,
perhaps even copying between regions which overlap - since then you need
to be able to choose whether it LDIRs or LDDRs. In that case you might
have something like
while(i++,a[i-1]=a);
to shift down, but
while(a=a[i-1],i--);
to shift up (of course you'd have to initialise i appropriately).
You have to be careful, though, not to invoke UB with something like
that (hence why I've used separate comma expressions to inc/dec i).


You're missing the point. The discussion is not about copying arrays.


/August
 
E

Edward

August said:
August said:
Would you also reject the string copy idiom

while (*t++ = *s++);

with the same motivation?
[...]
if using the result of an assignment as a condition
you should enclose in an extra set of brackets. Typically your compiler
should warn you otherwise (as you might have meant == instead).

Why should we as C programmers allow ourselves to be dumbed down by the
compiler? We know what we're doing, right? (Just trying a different
standpoint.)
.... because useful warnings that prevent common mistakes are a Good Thing?
Of course, unless you want to compare to something other than zero,
string.h's strcpy() would be more appropriate.
The interesting one, though, is if you want to copy within an array,
perhaps even copying between regions which overlap - since then you need
to be able to choose whether it LDIRs or LDDRs. In that case you might
have something like
while(i++,a[i-1]=a);
to shift down, but
while(a=a[i-1],i--);
to shift up (of course you'd have to initialise i appropriately).
You have to be careful, though, not to invoke UB with something like
that (hence why I've used separate comma expressions to inc/dec i).


You're missing the point. The discussion is not about copying arrays.


/August

Except that the code snippet you gave was copying strings, and strings
behave very similarly to arrays of char under many circumstances. Of
course, I could have contrasted "t=s+1; while(s++=t++);" with "t=s+1;
while(t--=s--);", but typically the latter would be problematic as
strings, though they end with (char)0, tend not to begin with it.
Hence, moving a string in-place to one character forward (eg. with the
intention of inserting a new character in front of it) is more likely to
be performed by treating the string as an array of char and using the
index, rather than the copied value, in the loop condition.

I should also note that the code I posted before has an off-by-one bug;
instead of i-- it should use --i.

-Edward
 
J

James Dow Allen

I don't avoid ++ on non-pointers: often the brevity seems
just right, especially in a common idiom like
for ( ; Foo; index++)
yet nevertheless I frequently write
baz += 1
especially when the fact the addend happens to be 1 exactly
seems incidental.

Wondering whether the coder knows ++x and x+=1 are the same????
Wondering is good, but you might be overdoing it.
If the author is too dumb to understand x++ then one has to wonder what
else they dont understand.

So if you happened on an x += 1 in my code, you'll assume
I don't understand C?? :)
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c

You seem to find the 2nd clause in your .sig amusing.
Perhaps you should seek wisdom in the 1st clause. :)

James Dow Allen
 

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,954
Messages
2,570,114
Members
46,702
Latest member
VernitaGow

Latest Threads

Top