Side effects in conditional expressions

  • Thread starter August Karlstrom
  • Start date
W

Willem

Keith Thompson wrote:
)> Edward wrote:
)> ) If it's ++ it's obviously 1 for the obvious reason (it's an index or
)> ) counter, indexing or counting something). Whereas, if it's +=, that
)> ) implies that there is something special about the added value - and that
)> ) that value might change.
)>
)> It only implies that it's special because you would use ++ where that is
)> not the case. If ++ did not exist, there would be nothing special about
)> += 1, and the 1 would not be seen as a magic number.
)
) Right, in a language that has "+=" but not "++", "x += 1" would be
) the idiomatic way to increment x.
)
)> In other words: you're using a circular argument.
)
) What's cirular about it? C is not such a language. In C, "++"
) is the idiomatic way to increment a variable.

Yes, but the argument is about *why* ++ is the idiomatic
way to increment a variable, so that *is* circular.

IIRC, somewhere in this thread somebody was pleading for the removal
of ++ and -- from the C language, and to use += 1 and -= 1 instead.
And that's what started this thread.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
E

Edward

Willem said:
Yes, but the argument is about *why* ++ is the idiomatic
way to increment a variable, so that *is* circular.

IIRC, somewhere in this thread somebody was pleading for the removal
of ++ and -- from the C language, and to use += 1 and -= 1 instead.
And that's what started this thread.


SaSW, Willem
I disagree. ++ does not carry the extra meaning (that the 1 being
incremented by is nonspecial) "because it's idiomatic"; it carries that
meaning because, by its nature, it must be so - ++ can only increment by
1, whereas +=1 could easily be +=2 instead.
Symbolic constants are idiomatic because they convey the semantics of
'this magic number 23 means /foo/'. ++, similarly, conveys semantics;
it says 'this increment being 1 is essential rather than accidental'.
In other, more pompous words, ++ is epistemae, +=1 is doxa.
Oh, and +=1 would still be doxa even in a language that didn't have ++.

-Edward
 
F

FredK

Keith Thompson said:
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?


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

To me it is simply more clear. Just because something is done by most
"experienced C programmers" doesn't mean it's a great idea. Many of the
choices of the C language and C programmers have led to decades of bugs and
security holes and billions of dollars in costs.

In this particular case, I am not religious about it - I qualified my
statement by "almost always". For example, I have no problem with using:

bar = array[index++];

as opposed to

bar = array[index];
index += 1;

even though they are likely to generate the same code. However, simply from
a style standpoint, I find a naked "index++;" ugly.

Why I don't use *x + 1 for pointers? Because I can never remember the
obscure C rules for pointer incrementing and I am 100% certain it will
confuse the next person who has to maintain the code - but I do know that
*x++ will increment it by the correct size to get to the next element.

FWIW - I think I started writing C code using Whitesmith C back on the
PDP-11. So I've written a butt-load of C code. I've never had anyone
complain about not being able to understand my code - and I've handed off
quite a lot of it to others to maintain.
 
F

FredK

Richard said:
Amazing. Really. I am gobsmacked that anyone here is claiming that x+=1
is EASIER and CLEARER than the obvious C shortcut of x++;

It kind of wreaks of new grads who start #defining begin and end and
trying to make their C look like their University pascal code ...

If x++ isnt clear to anyone here they have no business writing C code.

Would you like cheese with your whine? I've written code in C since the
PDP-11 was all the rage. As far as I know, I've never written a buffer
overflow - I suppose that excludes me from having any business writing C
code.

Get a life.
 
F

FredK

For some of my recent source, I just did
grep "+= 1;" */[a-z]*.c
I was surprised at how many instances there were!

Snipped the rest of this very good post because my reader wouldn't quote it,
and for brevity.

Thanks. Exactly.
 
K

Keith Thompson

FredK said:
To me it is simply more clear. Just because something is done by most
"experienced C programmers" doesn't mean it's a great idea. Many of the
choices of the C language and C programmers have led to decades of bugs and
security holes and billions of dollars in costs.

Speaking of clarity, your first sentence means that "x += 1" is simply
more clear than "x++", right?

Do you seriously think that using "x += 1" in preference to "x++" will
prevent bugs?

If you prefer "x += 1" to "x++", that's fine; I have the opposite
preference in most cases, but I'm not going to tell you you're wrong.
If you don't have any rational basis for your preference, that's
ok too. But the "decades of bugs and security holes and billions
of dollars in costs" argument is simply irrelevant.
In this particular case, I am not religious about it - I qualified my
statement by "almost always". For example, I have no problem with using:

bar = array[index++];

as opposed to

bar = array[index];
index += 1;

even though they are likely to generate the same code. However, simply from
a style standpoint, I find a naked "index++;" ugly.

And that's where my own point of view (and, I think, that of most
C programmers) differs from yours. I find "index++;" perfectly clear
and idiomatic.
Why I don't use *x + 1 for pointers? Because I can never remember the
obscure C rules for pointer incrementing and I am 100% certain it will
confuse the next person who has to maintain the code - but I do know that
*x++ will increment it by the correct size to get to the next element.

But I didn't ask about *x + 1; I asked about "x += 1".
No dereference, no operator precedence concerns. From what you've
been saying, I get the impression that you prefer "x += 1" if x is
of integer type, but "x++" if x is of pointer type. I find that odd.

(But I'm sure I have some coding habits that others would find
equally odd.)
FWIW - I think I started writing C code using Whitesmith C back on the
PDP-11. So I've written a butt-load of C code. I've never had anyone
complain about not being able to understand my code - and I've handed off
quite a lot of it to others to maintain.

I have no problem understanding "x += 1", nor would anyone else
who is at all qualified to be reading C code in the first place.
But unless the context is such that the "1" could have been
something else, I prefer "x++" (I'm assuming statement context, so
the distinction between "x++ and "++x" is irrelevant). And if I see
"x += 1" where I would have written "x++", I know exactly what it
means, but I have to wonder why it was written that way.
 
F

FredK

Keith Thompson said:
FredK said:
Keith Thompson said:
[...]


Speaking of clarity, your first sentence means that "x += 1" is simply
more clear than "x++", right?

Do you seriously think that using "x += 1" in preference to "x++" will
prevent bugs?

Prevents bugs? Perhaps. But I didn't write my response as strongly as you
seem to think I did. When given a choice between providing clarity to the
next programmer who will maintain my code, I try to choose the expression
that will be least confusing. I simply find that naked pre and post
increment operators less intuitive but += obvious. But you can take it
simply as a matter of style - it simply doesn't fit my eye.
If you prefer "x += 1" to "x++", that's fine; I have the opposite
preference in most cases, but I'm not going to tell you you're wrong.
If you don't have any rational basis for your preference, that's
ok too.

Decades ago when I debugged someone elses shipping code that used x++; when
he meant *x++; - I adopted the style I use today in my own code. Does it
stop me from making the same error? Who knows? But in my own code, I would
find a naked "x++;" suspect. If it generated worse instructions, I'd easily
change my style. But it doesn't.
But the "decades of bugs and security holes and billions
of dollars in costs" argument is simply irrelevant.

This (perhaps unfortunate) comment was knee jerk to the "experienced C
programmer" comment - which I found irrelevant (and a little insulting).
Choosing a style simply because a mythical "experienced" C programmer might
do it another way is silly IMHO.
But I didn't ask about *x + 1; I asked about "x += 1".
No dereference, no operator precedence concerns. From what you've
been saying, I get the impression that you prefer "x += 1" if x is
of integer type, but "x++" if x is of pointer type. I find that odd.

(But I'm sure I have some coding habits that others would find
equally odd.)

We agree.
I have no problem understanding "x += 1", nor would anyone else
who is at all qualified to be reading C code in the first place.

I guess I've been writing code for too long. I've had to deal with many
people writing code in C who arent qualified to read C. You have examples
of it weekly in this newsgroup. After all these years, I do not make
assumtions about the people who will eventually have the "privlege" of
maintaining my code and their qualifications. Long experience has taught me
that compilers are smarter than I am, but programmers may not be. So unless
some expression is obviously a performance killer in a critical path,
clarity (including comments) is more critical than C style points or clever
use of language features.
But unless the context is such that the "1" could have been
something else, I prefer "x++" (I'm assuming statement context, so
the distinction between "x++ and "++x" is irrelevant). And if I see
"x += 1" where I would have written "x++", I know exactly what it
means, but I have to wonder why it was written that way.

OK. So

x++;

which is all too common of an occurance (a generic variable name) is more
clear to you than:

x += 1:

which would confuse you?

How about

myStruct->reference_count += 1;

Do you really find that unusual or confusing? As someone else who agrees
with you posted who did a search on his own code... apparently the degree of
being unusual is less than you might suspect.
 
K

Keith Thompson

FredK said:
OK. So

x++;

which is all too common of an occurance (a generic variable name) is more
clear to you than:

x += 1:

which would confuse you?

I never said it would confuse me. I know exactly what it means. It
would just cause me to wonder why the author chose to write "x += 1;"
rather than "x++;".

One very real possibility, in the absence of other information,
is that the author doesn't know about the "++" operator. I do
not suggest that this applies to you, but if you write your code
under the assumption that the reader might be uncomfortable with
"x++;", then I can certainly read code under the same assumption
about its author.

Or maybe the author is accustomed to Python (which has "+=" but not
"++").

I'm guessing that if you saw "x = x + 1;", you'd wonder why the
author didn't write "x += 1;". It's the same kind of thing.
If "x = x + 1;" could as easily have been "x = y + 1;", then it
makes sense to make the whole thing explicit; if not, "x += 1;" is
a good shorthand. Similarly, if "x += 1;" could as easily have been
"x += 2;", then it makes sense for the 1 to be explicit; otherwise,
"x++;" is a good shorthand.

I don't suggest that this is hard and fast rule that everyone should
follow.
How about

myStruct->reference_count += 1;

Same thing.
Do you really find that unusual or confusing? As someone else who agrees
with you posted who did a search on his own code... apparently the degree of
being unusual is less than you might suspect.

Unusual: yes, slightly. Confusing: not inherently; it just makes me
wonder what was in the author's mind.
 
I

Ian Collins

I never said it would confuse me. I know exactly what it means. It
would just cause me to wonder why the author chose to write "x += 1;"
rather than "x++;".

I'd wonder why they didn't write "++i", which just goes to show how
subjective style is!
 
F

FredK

Keith Thompson said:
FredK said:

[...]


Or maybe the author is accustomed to Python (which has "+=" but not
"++").

I make too much money to write Python code, which I have never even looked
at.
I'm guessing that if you saw "x = x + 1;", you'd wonder why the
author didn't write "x += 1;".

Not at all. I've read far too much C code over the years to be confused.

[...]
Same thing.


Unusual: yes, slightly. Confusing: not inherently; it just makes me
wonder what was in the author's mind.

To each his own. I would not even blink if I saw "myStruct->reference_count
+= 1;" in code as being unusual, or wonder what was in the authors mind.
 
S

Seebs

Why do you care what was in the author's mind?

Because understanding the author is a very big help in understanding the
code.

If I'm looking at code, 99% of the time the reason is that Something Is
Wrong. Understanding the mindset and beliefs of the programmer helps
me find out where it is.

A couple of weeks ago, we had a bug reported against our toolchain. A
particular application was crashing when prelinked. (The "prelinker" is
a clever hack which caches most of the work the dynamic linker would
otherwise have to do to reduce startup times.) This is usually assumed
to be a toolchain bug.

Three minutes into looking at the bug, I informed people that the problem
would probably be a bug in the software package in question. Why? Because
the code was badly written. Nothing specifically wrong, just poor style,
questionable layout. Trivial stuff, but it leapt out as signs that the
writer didn't really understand C.

Sure enough, we did (after quite a bit of work) track the problem down to
an uninitialized variable, which had been getting zeroed-out space before
but was now getting stack garbage.
Mucking around with
petty style questions is, in my incredibly humble opinion, a
waste of time and not at all professional.

The thing is...

They're not necessarily a big deal. But they're often a big early warning
sign that there will be big deals. My experience has been that good
programmers are consistently careful about things, and that even "petty"
style things can be a warning sign of someone who's careless or inconsistent,
or unfamiliar with the language.

Something unidiomatic makes me suspect that I will find other unidiomatic
things... and since many C idioms are idioms because they provide protection
against common failure modes, that tells me to look there first.

Heuristics are awesome. ... As long as you understand that they are
heuristics, not Revealed Truth.

-s
 
J

James Dow Allen

PLEASE be aware that my position is not particularly
that "+= 1" is *better* than "++". On the contrary,
my position is that those obsessed with the betterness
of one or the other suffer an excess of obsession. :)

Two Days ago we had:
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++".

OK. Agree to disagree. I've never wondered why an author
used x++ when x += 1 would seem more appropriate to me.
Perhaps I just lack curiosity.
"x++" ... [is] just clearer to most
experienced C programmers.

Actually "x += 1" often seems slightly clearer to me, for
the simple reason that it uses more ink! When scanning code
at high speed it will stand out better than a "++", especially
since the convention is to provide no space with "++".

All other things equal, the extra ink would be a *slow-down",
but here it's only a tiny bit of extra ink and it's pulling
its own weight.

We all agree to dislike strung-together ops that avoid the
straightforward A = B; C = D; E = F; formula. Can't you
see that
foop->child[0]->count++;
is in a sense too "strung together" compared with
foop->child[0]->count += 1;

BUT PLEASE know that I'm not trying to make a case
against "++" here. I'm just saying a case is makeable
and the pedantry that "+= 1" is the mark of a novice
is almost unbelievably AMAZING !

I never said it would confuse me.  I know exactly what it means.

Are you getting defensive or what? Obviously you know
what the C expression "x += 1" means. (????!!!!)
By "confused" we meant that you implied the expression
would slow you down while you contemplated the
hidden meaning of the instance of ++ avoidance.
One very real possibility, in the absence of other information,
is that the author doesn't know about the "++" operator.

One wonders if you're serious. C programmers with
a few weeks of experience are likely to use ++ too often,
not too seldom. If the programmer is as novice as you suggest,
there will be plenty of evidence without scrutinizing his "+= 1".
I'm guessing that if you saw "x = x + 1;", you'd wonder why the
author didn't write "x += 1;".  It's the same kind of thing.

Not quite. The side-effects-only-once feature of C applies
to BOTH ++x and x += 1, but NOT x = x + 1; I'd guess this fact
would be second-nature to a C programmer even when x is a simple
variable without side effects. (After all, if nothing else 'x'
has the "side-effect" that our eyes waste time scanning it. :)

The appropriate use of ink criterion for helping code to be
scanned at high speed does not condone the duplication of 'x'.
Speaking only for myself, "x = x + 1" would look peculiar
in a way "x += 1" does not.
Unusual: yes, slightly.  Confusing: not inherently; it just makes me
wonder what was in the author's mind.

You've got me curious now. Can you post any fragment of others'
code you've needed to maintain where such wondering turned out to
be productive?

James Dow Allen
 
A

August Karlstrom

One wonders if you're serious. C programmers with
a few weeks of experience are likely to use ++ too often,
not too seldom. If the programmer is as novice as you suggest,
there will be plenty of evidence without scrutinizing his "+= 1".
Agreed.

The side-effects-only-once feature of C applies
to BOTH ++x and x += 1, but NOT x = x + 1

No, there is only one side effect in `x = x + 1' as well.
The appropriate use of ink criterion for helping code to be
scanned at high speed does not condone the duplication of 'x'.
Speaking only for myself, "x = x + 1" would look peculiar
in a way "x += 1" does not.

The statement `x = x + 1;' is obvious to anyone (except for the fact
that an equal sign is used for assignment) so I wouldn't call it
peculiar. It also resembles x ↠x + 1 which is often used in algorithm
texts (left arrow for assignment). But as I said before, I'm fine with
all three versions.


/August
 
N

Nick

James Dow Allen said:
For some of my recent source, I just did
grep "+= 1;" */[a-z]*.c
I was surprised at how many instances there were!


You inspired me to do the same.

One was a desperate bid to persuade a compiler that an unused function
parameter really wasn't used (!)

A couple where simple "increase the counter at this point". In each
case, they were in places where a ++ as part of another statement
wouldn't fit in tidily.

And a couple of the others where:
if(xxx)
x += 1;
if(yyy)
x += 2;

So I think I prefer x+=1; to a bare x++; (or ++x;) but if it was ever
possible to write y=x++; without making the code unbearably convoluted
I'd do that instead.

I'm reasonably happy with that convention.
 
J

James Dow Allen

James Dow Allen said:
For some of my recent source, I just did
grep "+= 1;" */[a-z]*.c
I was surprised at how many instances there were!

You inspired me to do the same.

I think such experiments are useful and interesting.
I hope others try various such experiments
and report results here.

For example, several months ago I reported on
grep "while (0)" glibc/*/*.c
Instances that turned up included 2 or 3 cases where the
"while (0)" was at the end of a macro AND FOLLOWED
immediately by ";" which was a bug, defeating the very
syntactic purpose (albeit often irrelevant) of that
special macro construction.

It also turned up some *VERY* peculiar Duff'sdevice-like
foolishness with no purpose but goto-avoidance....
One was a desperate bid to persuade a compiler that an unused function
parameter really wasn't used (!)

That recalls Sir Walter Scott's _Marmion_, Canto VI (The Battle),
Stanza 17, lines 27-28, doesn't it? :)
So I think I prefer x+=1; to a bare x++; (or ++x;) but if it was ever
possible to write y=x++; without making the code unbearably convoluted
I'd do that instead.

I also may occasionally vary my preferences to save a little
vertical space, but hate to mention that here as another
content-free flamefest is likely to ensue. :)

James Dow Allen
 
D

David Thompson

Decades ago when I debugged someone elses shipping code that used x++; when
he meant *x++; - I adopted the style I use today in my own code. Does it

IHopeYM (and he meant) (*x)++. As a statement (value discarded)
*x++ is the same as x++, and ++*x is the same as ++(*x) or (*x)++.
stop me from making the same error? Who knows? But in my own code, I would
find a naked "x++;" suspect. If it generated worse instructions, I'd easily
change my style. But it doesn't.

FWLIW personally I tend to prefer prefix ++x (and --x) as a statement,
or in other non-value context like the third item in a for(;;),
primarily because in the dim past I spent quite a bit of time using a
proprietary (now vanished) language which had special *statements*
for increment and decrement, with the keyword preceding the operand
(as statement languages typically do), and I just got used to it.
But I certainly don't claim it's objectively better.

COBOL has, or had when I knew it, ADD delta TO var for numeric
(and several other specific forms as well as COMPUTE var = expr)
but SET var { UP | DOWN } BY delta for 'index' (quasipointer).
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top