Friday, March 19, 2021

A diabolical for-loop

Older people sometimes think that experience is knowledge. Sometimes it is, and sometimes it isn’t. In my experience.

Look at this:


Ooops now, sorry, that's it for those of you who are not technically minded. You can stop reading now, just after you consider this post sent to me by my daughter. Who must have thought, for some reason that I would appreciate the sentiment:


 Bye. Now for those remaining this...


...caused me some grief. It is the last part of a for loop:

    for (int e = 0 ; e < ikNumDegSymbols ; e = e++) {
        if (eIn == kDegsDescs[e].e) {
            return kDegsDescs[e].pszDesc;
        }
    }

What is strange is that I normally use e++, or i++ or whatever....

    for (int e = 0 ; e < ikNumDegSymbols ; e++) {

I must have been tired or dreaming when I used e = e++. But it has worked for years, this unnoticed glitch, in this one for-loop.

It worked until it didn't, one day the behaviour changed, suddenly the for loop never exited, and debugging revealed that e was stuck at was some random value, 23567 for example. At most it should have done 3 loops.

I asked some programmer friends, and they enlightened me. In the C++ language the behaviour of e=e++ is undefined! I'd never even considered that to be a possibility. Uninitialized variables are one thing, an increment and assignment being undefined is another.

Undefined behaviour means that the compiler can do WTF it wants. And an upgrade to the compiler had changed how it interpreted e = e++. I have no idea what it thinks of that operation now, seems almost like an unitialised variable.

One programmer in particular, Alessio Nava, much younger than me, said he always used ++e, the behaviour of which is defined. So now I always use ++e.

Oh well, older people sometimes think that experience is knowledge. Sometimes it is, and sometimes it isn’t. In my experience.







2 comments:

  1. Let me first establish my credentials: I will be 71 next week, which places me firmly in the "older people" category. I will be celebrating it while continuing to explore the fuzzy edges of the C++ concurrency model in C++20. My incentive is the need to port some 250,000 lines of multithreaded C++ code that has been continuously developed over the past 28 years from Windows to Linux (and beyond).

    Regarding experience (E) and knowledge (K), they are two separate classes. Each instance of experience is constrained to grow approximately linearly over time, while knowledge, based on experimental evidence over the past half-millennium or so, appears to grow approximately exponentially. It was therefore true that E = K in the past when knowledge was gained through apprenticeship, but no longer.

    Leon Battista Alberti wrote some six centuries ago that, "A man can do all things if he will," embodying the Renaissance ideal of the "Universal Man" (Uomo Universale). Contemporary with Leonardo da Vinci, Alberto was an accomplished architect, painter, classicist, poet, scientist, mathematician, and oh yes, a master horseman. Show me a self-proclaimed Renaissance Man today and I will show you a self-deluded grifter -- it is simply not possible. E(t) < K(exp(t).

    But now to specifics -- being a skilled programmer has little to do with experience, other than recognizing that every new software development paradigm is simply a renamed approach from more than a decade before. The only advantage of experience is in recognizing patterns (which Edward Yourdon discussed decades before the Gang of Four) in problems and choosing appropriate solutions.

    Underlying the usefulness of experience is the Pareto Principle -- much of what you learn will never prove useful in what you do, but it lays a foundation that allows you to put what is useful into context. Ask why the brilliant blue of a Morpho butterfly's wing does not change color with viewing angle and you may spawn a 100-million dollar holographic industry when you put what you discover to use. (True personal story, but not important here).

    Finally, the curious case of pre- and post-incrementing a variable in C++, and the related question of which operator is more efficient in time and memory. Twenty-five years ago, it would have taken a very close reading of Bjarne Stroustrup's "The Annotated C++ Reference" to glean an answer. Today, it is as simple as searching for "post increment vs pre increment c++ undefined," which will lead to (among many other hits) www.http://www.cplusplus.com/forum/beginner/135021/.

    ... and there is the hidden variable in this discussion. It may be true that E(t) < K(exp(t) these days, but our experience is now collective rather than individual. We currently rely on stumbling across blogs such as "Ransen's Technical Stuff," but this will soon seem as quaint as perusing papyrus scrolls in the Library of Alexandria for imparting knowledge. Like it or not, the Collective Mind is coming (and hopefully without the poorly-engineered cybernetics of The Borg).

    We will all be assimilated, and I hope to live long enough to experience the fusion of experience and knowledge.

    ReplyDelete