embedded software boot camp

Shifting Styles

Thursday, November 27th, 2014 by Nigel Jones

To say it’s been some time since I last posted is an understatement! I won’t bore you with the details other than to note that sometimes there just aren’t enough hours in a day.

Anyway, today’s post is about a stylistic issue I’ve noticed in just about all code I’ve ever looked at. Unless you are a closeted BASIC programmer, you probably don’t ever write something like this:

foo = foo + 6;

While there’s nothing particularly wrong with this, other than looking rather odd from a mathematical perspective, just about every C programmer would use the += operator, i.e.

foo += 6;

Indeed this is true for all the arithmetic and logical operators. I.e.

foo *= 6;
foo /= 6;
foo -= 6;
foo ^= 6;
foo |= 6;
foo &= 6;

However, when it comes to the shift operators, something odd seems to happen. Almost no one writes:

foo >>= 6;

or even rarer:

foo <<= 6;

Instead folks resort to the syntax of BASIC and use:

foo = foo >> 6;
foo = foo << 6;

Why exactly is this? This thought was triggered by me looking at some of my own code from about ten years ago. Sure enough right in the middle of what was an otherwise well written piece of code (in the sense that ten years later it was easily followed and was a breeze to adapt to my latest project) I found a:

foo = foo << 6;

I have no real explanation other than we are all creatures of habit and sometimes get into inconsistent programming styles. While I wouldn’t fault someone for doing this, I do think that if you quite happily use += but not >>= then you should ponder your rationale for being inconsistent. Perhaps it will trigger a bigger introspection?

 

Tags:

11 Responses to “Shifting Styles”

  1. Jeff Gros says:

    Hi Nigel,

    I’m glad you’re posting again. It seems to me that most of the good embedded blogs have been running dry of content in recent years. I’m always happy to read what you have to say.

    I’ve always used the foo <<= 6 notation if that was all that I was doing for that expression.

    However, if I was implementing something more complex, like a digital filter, then I probably would have broken it up like you did.

    To me the argument for one versus the other comes down to code clarity and good documentation.

    Thanks

    Jeff

    • Nigel Jones says:

      Thanks for the kind words Jeff. Apologies for taking so long to approve your comment (and the others below). For some reason I didn’t receive notification that you had posted it.

      As to your point, I think it’s an interesting one of consistency versus clarity. I’d tend to favor clarity over everything else, but then you get into what’s clear and what isn’t. I ‘ve certainly known folks that don’t see a problem with int ***foo!

  2. Steve Langstaff says:

    The examples where the short version is commonly used all have one character operators (excluding the ‘=’) whereas the examples which do not commonly use the short version have two character operators.

    I wonder whether it is because we mentally group the three characters of ‘>>=’ into ‘>’ and ‘>=’, get confused and fall back to the long form?

  3. Ben says:

    I don’t like the shift-assign operators because they look like some exotic relative of assignment (like read from a channel/stream or something like that). FWIW the right-shift-assign operator is the monadic bind operator in Haskell.

  4. Leonard Dee says:

    I have done this, too. I don’t use the >>= style of syntax, for shifting, because most coders are unfamiliar with it. In my jobs, my code has done lots of math and logic operations, but very little shifting. When I (and many of my colleagues) come across ‘foo >>= 6’, we have to pause, and ask ourselves “what is going on here?”, before remembering. Some of them are completely flummoxed by it, and instead of looking it up themselves, they will track me down and ask me. When I use the long form (foo = foo >> 6), I (and the reviewiers/maintainers) figure it out faster.

    As a consequence, I usually switch to the longer style, for just the shifting code.

  5. I guess I’m the “almost no one” because I use the <>= forms. I’ve done this ever since day 1 since it’s a cleaner way to do it.

    And you can also do it with the modulo operator.

    foo %= 60;

    is the same as

    foo = foo % 60;

    Although doing this with the modulo operator is rare, I have used it this way in parsing times.

  6. Lundin says:

    I tend to use both forms, though the foo = foo >> 6; has some advantages when you want to be overly clear and explicit.

    The shift operators in C are special beasts when it comes to implicit type promotions. Integer promotion applies to both operands as for any C other operation, but balancing (usual arithmetic conversions) does not. Instead, the standard says that the result type of the shift is that of the promoted left operand. Now if I write foo >> 6, there is no doubt to me what the type of the left operand is, but if I write foo>>=6; then it isn’t really obvious. Consider this:

    uint8_t byte = …;
    byte = byte >> 6;

    Several type promotions/demotions appears between the lines, so what the program actually gets tasked to do when you write the above, is something obscure like this 100% equivalent code:

    byte = (uint8_t) (int) ((int)byte >> 6);

    where (int)byte is the first implicit integer promotion, (int)(byte >> 6) is the type that the result of the shift will get, because of the special rule for shifts, and (uint8_t) is the implicit type demotion that you get when trying to show an int into a uint8_t.

    In order to demonstrate to the reader of your program that 1) you actually have a clue about the various implicit type promotions and 2) have actually considered all the potential bugs that could be caused by them, you could write your code with explicit casts as

    byte = (uint8_t) ((uint32_t)byte >> 6u);

    which is also required to make the code MISRA compatible (assuming 32 bit CPU). The expression byte>>=6 cannot be rewritten explicitly like this, and therefore can never be MISRA compatible either.

  7. Bernhard Weller says:

    It actually never came across my mind that it is possible to use <>=, they just don’t seem right – sure I only have roughly 3 years of coding experience in C/C++.
    Why is it?
    I guess it’s what Steve said. Let’s see what might be happening:
    Our brain is being trained recognize >= and <=, so that's the pattern which we see first and already start to think in a direction of a condition. Then we realize, that there is another , and while rarely used, we might remember something like >> or << from physics where it was used to state "much bigger/smaller" – so in the end we might end up with a condition worded like: "much bigger/smaller or equal" – which would be a really interesting concept (and very useless in any real world scenario I guess, and quite vague for a compiler instruction).

    Out of curiosity I searched through the code of the last projects I was involved in, and I found only two occurrences in a FFT algorithm and some floating point conversion from PIC to IEEE.

    Quite interesting was another result I found in a CRC-implementation from pycrc:
    for (i = 0; i < data_len; i++)
    {
    if (data & 0x01) {
    ret = (ret << 1) | 1;
    } else {
    ret = ret <>= 1;
    }
    return ret;

    Now that’s shifting styles quite quickly.

    • Bernhard Weller says:

      Okay, html and > < are quite hard to use.

      Let's try this again:
      for (i = 0; i < data_len; i++)
      {
      if (data & 0x01) {
      ret = (ret << 1) | 1;
      } else {
      ret = ret << 1;
      }
      data >>= 1;
      }
      return ret;

Leave a Reply