Page 18 - EETEurope FlipBook February
P. 18

18 EE|Times EUROPE



         EMBEDDED
        Surprises in C Code


        By Colin Walls









                                                                                                                   IMAGE: SHUTTERSTOCK









              he C language is quite flexible and expressive — two of the   Of course, this might be written more compactly as:
              reasons that it has been successful and resilient against
              replacement by “better” languages. An example of its flexi-  alpha = beta = gamma = 99;
        T bility is the possibility to write an expression in a number of
        ways that are functionally equivalent. This enables the style of coding   These are 100% equivalent. Or are they?
        to be adapted to personal needs, but there’s a catch: Sometimes,   Most of the time, these two constructs are entirely equivalent, but
        apparently equivalent code has subtle differences. This can occur   there are (at least) four situations in which choosing one or the other
        even in the simplest code.                            might make a difference.
          It is common for C to provide several ways to do something, all of   First, and most prosaically, each variable is separate, and perhaps a
        which are exactly equivalent. For example, given that x is a normal   comment indicating why it is set to this value might be appropriate.
        int variable, each of the following statements will do exactly the   Second, it is always good to write maintainable code. At some point
        same job:                                             in the future, the code might need to be changed so that all three vari-
                                                              ables are not set to the same value. The first format lends itself more
          x = x + 1;                                          readily to modification.
          x += 1;                                               The third reason relates to substandard compilers, which might
          x++;                                                generate code like this for the first construct:
          ++x;
                                                                mov r0, #99
          In each case, 1 will be added to x. The only possible difference is   mov alpha, r0
        that a less capable compiler might generate slightly better code for the   mov r0, #99
        last two options (which would be a hint that getting a better compiler   mov beta, r0
        would be worthwhile).                                   mov r0, #99
          The two forms of the ++ operator, used in this way, produce the same   mov gamma, r0
        result. However, if the value of the expression is used, the pre-
        increment and post-increment are different, thus:       The second construct gives the hint that r0 needs to be loaded only
                                                              once. Again, a better compiler would not need the hint.
          y = x++;    //  x before the increment                Finally, there is the question of execution order. In the first con-
          y = ++x;   // x after the increment                 struct, it is entirely clear that alpha will be assigned first and gamma
                                                              last. A compiler will interpret the second construct like this:
          Interestingly, the post-increment is slightly more “expensive,” as
        storage needs to be allocated to keep the old value of x. However, a   alpha = (beta = (gamma = 99));
        compiler would probably optimize this away. If the storage is allocated
        when the expression value is not used, then a new compiler is definitely   This means that the assignment order is reversed. But does that mat-
        required.                                             ter? Most of the time, it does not. But if these were device registers, not
          If, instead of being an int, x were a pointer to int, the adding 1 would   ordinary variables, it might make a big difference. It is very common
        have the effect of adding 4 (on a 32-bit machine). If this comes as a big   for hardware to need set-up values in order to be loaded in a precise
        surprise, a brush-up on pointer arithmetic is in order.  sequence.
          However, sometimes constructs that appear to be equivalent have   So I would say that the multiple assignments in one statement
        very subtle differences.                              construct should be avoided. Overall, although C is a small language, it
          Probably the simplest thing that you can do in any programming   could be argued that C could be even smaller if there were fewer ways
        language is assign a value to a variable. So, in C, we might write:  to do things.
                                                                The result might be clearer, more maintainable code. ■
          alpha = 99;
          beta = 99;                                          Colin Walls is an embedded software technologist with Siemens EDA.
          gamma = 99;                                         This article was originally published on Embedded.

        FEBRUARY 2021 | www.eetimes.eu
   13   14   15   16   17   18   19   20   21   22   23