Alternatives to modifying loop var in the loop.

Discussion in 'C Programming' started by Matt, Dec 27, 2013.

  1. Matt

    Phil Carmody Guest

    Sometimes even variable names can be enough of a clue, but yes, that
    single line is enough of an idiom that it carries a lot of baggage about
    what one would expect to follow.
    I notice that one example was a for() and the other was a while().
    I'm a great believer that people over-use for() - I hate seeing ``; )'',
    for example. That immediately says "should have been implemented as a
    while loop" to me. My expectations are different from the two constructs

    Phil Carmody, Dec 29, 2013
    1. Advertisements

  2. Matt

    Phil Carmody Guest

    If we're hypothesising, then why not have the default zero initialiser
    syntax be = {}; ? 2 initialisers is some. 1 initialiser is some. 0
    initialisers is none. If isolating a special case, surely the one that
    stands on its own (none, vs. some) is the best one to choose?
    I have a few "favourites" which I like less.
    Phil Carmody, Dec 29, 2013
    1. Advertisements

  3. Matt

    Seebs Guest

    Hmm. You may have a point.
    I'm not sure that's right. Or rather: Even if things are subjective,
    they may still be useful criteria. They may be observer-variant, but I
    would tend to consider "pleasant to work on" a significant trait to
    consider when evaluating prospective projects.
    That's not surprising. Comments that tell you what's supposed to happen
    are likely to make you expect that to be what happens.

    I usually aim comments at explaining why I do something unexpected
    that took a while to figure out. Otherwise, code is usually pretty
    comprehensible if it's reasonably clear.

    Seebs, Dec 29, 2013
  4. Interestingly enough, the actual, original definition of "elegant" is
    "minimalist". Which, in the context of the religion of CLC, ends up
    meaning exactly the opposite of "clarity" (since "clarity" usually ends up
    meaning "be as verbose as possible").

    The problem in US politics today is that it is no longer a Right/Left
    thing, or a Conservative/Liberal thing, or even a Republican/Democrat
    thing, but rather an Insane/not-Insane thing.

    (And no, there's no way you can spin this into any confusion about
    who's who...)
    Kenny McCormack, Dec 30, 2013

  5. See, that's *exactly* the kind of response I was looking for. It teaches
    me an alternative way of doing things I myself had doubts about when
    doing them the way I did them.

    As to the 'elegance' discussion, I though for a while what word to use
    and basically chose 'elegance' over others because I thought it had the
    higest chance of conveying the intended meaning and producing the desired
    response. The fact I got the response I wished for basically proves my
    choice right. :)
    Aleksandar Kuktin, Dec 30, 2013
  6. Matt

    Matt Guest

    I plugged the new getscore in to the apple][ code and got a performance
    gain. 15min wait on the first pass vs 20min previously.

    I think I discovered something else though.

    Looking at a single conceptually boolean int to see whether it is
    necessary to do something to something seems like a trivial operation.

    What if you did it 1296 * (15 * 1296) times and only 1296 * (1 * 1296)
    of them were necessary? Could this slow your program down?

    If anyone is curious the offending code is the loop at line 178 of

    I think Eric was on the money when he said
    And I was on the money when I said
    Matt, Dec 30, 2013
  7. Matt

    Jorgen Grahn Guest

    It's also terribly ugly, IMO. "The cure is worse than the disease" is
    a phrase which comes to mind. A big part of the appeal of for loops
    is "look, here's all you have to know about how 'i' changes, in one
    single line".

    (I don't think I've seem it before, except of course the form with an
    explicit "please stop the loop" flag -- 'i < len && !stop')

    Jorgen Grahn, Dec 30, 2013
  8. Matt

    Eric Sosman Guest

    Still seems far too long. See below.
    If you drank fifteen times your normal intake of beer,
    could this slow *you* down? ;-)

    Might this account for your fifteen minutes? Let's use the
    back of this handy envelope here: 25e6 tests divided by 900 seconds
    is 28000 tests/sec, or 36 microseconds/test. You've mentioned that
    you're using an emulator for an elderly machine, and "36 MHz" might
    be in the right ballpark. If the host machine's instruction set is
    dissimilar to that of the emulated system, the emulator may well
    be an interpreter; such things often execute dozens to hundreds
    of host instructions for each emulated instruction. If the test
    and branch amounts to four or five emulated instructions, a twenty-
    fold dilation would turn "36 MHz" into "3 or so GHz," which would
    be something akin to what one would get from a present-day machine.

    Of course, this doesn't *prove* the extra work is soaking up
    all or even most of your time, but the numbers seem plausible and
    do not rule out the possibility. I think you'd do well to give
    this matter further attention.
    Eric Sosman, Dec 30, 2013
  9. Matt

    Jorgen Grahn Guest

    Me too, but I don't seem to see it a lot. My feeling is people abused
    for() more in the past, perhaps because the optimizers were worse.
    Yes. 'for' is IMHO good for a few (but common!) cases only.

    Jorgen Grahn, Dec 30, 2013
  10. Matt

    Jorgen Grahn Guest

    Yes. (Also, even the interesting properties you /can/ measure are
    usually infeasible to measure. You won't have a team of psychologists
    and a study group handy when it's time for code review ...)

    Almost all conflicts I have with coworkers, people on Usenet, previous
    authors of code I have to maintain, etc ... are about subjective
    things. E.g. the code is reasonably correct, but it's not as easy
    (pleasant) to work with as I'd like it.

    Frustratingly, too often (most of the time, it seems) what's readable
    to one person is not very readable to all others. Only the people who
    just don't care are unaffected.

    Clarity as a concept doesn't seem a lot more helpful. Your background
    and way of thinking has too much of an impact on what you see as

    Jorgen Grahn, Dec 31, 2013
  11. Matt

    Eric Sosman Guest

    Botch. Botch, botch, botchety-botch-botch-botch.

    "Hold it right there, fella. Put down the pencil, and step
    away from the envelope. Okay, let's see your estimating license.
    No, take it out of your wallet first, that's right. Well, well,
    what have we here? Estimating with a suspended license? Don't
    explain to me; save it for the judge. You have the right to
    remain silent, ..."

    "Honestly, Your Honor, I don't know what came over me. The
    cat was trying to get my attention and maybe that distracted me,
    but I still don't know why I pushed one-over-ex after calculating
    a rate, and then called *that* a rate, and mangled the units, too.
    28000 tests/sec has nothing to do with `36 MHz' -- it's 28 kHz or
    0.028 MHz, as any fool can plainly see. No offense, Your Honor.
    And all that stuff about a hundredfold slowdown explaining the
    difference between `36 MHz' and a modern machine -- well, it's
    completely off the mark, I see that now. It'd take something like
    a hundred-thousand-fold slowdown to cover the actual discrepancy,
    and that's more than I'd like to believe in. It'd still be good
    for him to figure out why he's doing fifteen times as much work as
    necessary, but that in itself won't account for his time."

    "No, Your Honor, I don't hold a grudge against him -- I don't
    even know him. I certainly wasn't trying to make trouble for him,
    I just blundered, that's all. Nothing malicious, just a thinko."

    "Uh, no, it's not my first offense. My worst, maybe, but not
    my first. How many? Well, in four-plus decades of estimating I
    must have-- Oh, right, sorry: With a suspended license, I shouldn't
    be trying to estimate how many estimations I've mis-estimated. All
    I can say is that there was no ill will, and that I'll be more
    careful in the future, and I plead for the Court's understanding."
    Eric Sosman, Dec 31, 2013
  12. Reminds me how often 1/x is misapplied. Resolution should be in
    spatial frequency (something per unit distance) not distance
    units. Otherwise "high resolution" has the wrong meaning.

    More intersting is shutter speed on cameras, which should be
    in reciprocal time units. That is, not (1/125) second, but
    125/second. (Which nicely agrees with the labels on the
    shutter speed dial, but not with the common description.)
    Again, high shutter speed needs to have the right meaning.

    Yes, the one-over-ex key gets pressed too often.
    (snip, really funny, too)

    -- glen
    glen herrmannsfeldt, Dec 31, 2013
  13. It does. I think you are confusing exposure time with shutter speed. A
    high shutter speed is exactly that -- a shutter moving very fast, giving
    rise to a very short exposure time.

    Ben Bacarisse, Jan 1, 2014
  14. (snip, I wrote)
    As with the post I replied to, some people put 1/x where it isn't
    needed or wanted.

    Often people will write shutter speed = (value with time units),
    where it comes out right for (value with reciprocal time units.)

    -- glen
    glen herrmannsfeldt, Jan 1, 2014
  15. Matt

    Matt Guest

    Wrapping up my participation in this thread:

    Because constantly rejigging my gcc code for the old compiler was
    tedious I ended up using the time taken for the gcc code to solve all
    1296 possible codes as a proxy for speed/efficiency/whatever, assuming
    any gains made would also manifest when I later rewrote for the 6502
    cross compiler.

    At one point I got a dramatic improvement:
    $ cat *w/time
    [...]01//a working version of the code
    1295 K3

    real 20m43.325s
    user 20m43.142s
    sys 0m0.048s

    [...]05//the next working version (02, 03, 04 all broken or still born)
    1295 K3

    real 7m13.622s
    user 7m13.563s
    sys 0m0.004s
    Because I would get fed up and start a wholesale rewrite in a new
    directory it's a little difficult to pin down exactly what was
    responsible for the improvement but here are some changes between the

    1. getscore function rewritten per Ben's advice.
    2. I stole Willem's loop (I really like that loop!). This had the effect
    of fixing the 15 times too much work thing I'm pretty sure.
    3. Fewer functions.
    4. Fewer structs appearing in parameter lists. More use of indexes then
    looking up the code later.

    But as for the single silver bullet I'd have to go back over it all to
    find out for sure.

    The improvement didn't really manifest in the 6502 version. Or it did
    but only after the first pass through the algorithm which still takes 13
    min. Weird. I've taken this over to comp.sys.apple2.programmer

    So I learned some things:

    Thing: If you break your code into lots of tiny functions you can end up
    seeing too many trees and not enough of the woods.

    Thing: If every time you change your code, you break it then maybe you
    had a tenuous or incomplete understanding of the algorithm to begin with.

    Thing: Modern implementations like gcc are a huge advance on what was
    available for the Apple //e in 1986.

    Thanks to all responders,

    Matt, Jan 1, 2014
  16. I'd be willing to assert that for most working C programmers today, the
    above code is (pick all that apply): strange, cryptic, weird, "clever", not
    "clear", etc, etc, and that an explicit form with a loop would be much
    better in their eyes.

    Because, as is true of just about every population, most working C
    programmers today are idiots. It's what managememnt wants.
    Kenny McCormack, Jan 2, 2014
  17. Excuse me, but.... how is this loop supposed to stop. Exactly?

    I assume it was meant to be something more akin to

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

    but that the other `=' got lost somewhere.
    Aleksandar Kuktin, Jan 2, 2014
  18. Matt

    Martin Shobe Guest

    It stops when *d++ = *s++ is equal to zero. In other words, when s
    points to a zero value. It does copy the zero.

    Martin Shobe
    Martin Shobe, Jan 2, 2014
  19. Matt

    James Kuyper Guest

    This is something I've always considered to be one of the basic idioms
    of C, which is discussed in some detail in K&R. I understood that
    discussion on first reading. Over several decades, I've learned that I
    must be fairly unusual in that regard - most of the C programmers I've
    challenged to provide a detailed explanation of how that construct works
    were unable to do so, so don't feel too embarrassed about not having
    understood it.

    That construct presents several tricky issues, starting with the
    question of which gets evaluated first, the * or the ++. The next issue
    is precisely which value is returned by the ++ expression. The next
    issue is what the value of an assignment expression is. Once you've
    thought through those issues, you should be ready to answer the key
    question: under what circumstances is the value of the expression
    *d++=*s++ equal to zero? Those are precisely the circumstances that will
    cause the while loop to terminate.
    James Kuyper, Jan 2, 2014
  20. Matt

    Geoff Guest

    And here we have the lesson in why the code, while correct and
    succinct, is easily misunderstood to be "strange". One has to stop and
    say, "er, what?".
    Geoff, Jan 2, 2014
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.