0
#include <stdio.h>

#define Alphabet    26

struct Data
{
    int iNum;
};

int main()
{
    #if 0
        int iNum = 0;
        while(1)
        {
            iNum = (iNum++ % Alphabet);
            printf("%d\n",iNum);
        }
    #else
        Data data = {0};
        while(1)
        {
            data.iNum = (data.iNum++ % Alphabet);
            printf("%d\n",data.iNum);
        }
    #endif

    return 0;
}

In #if branch,print 1-26;but in #else branch,print 1,2,3,.... This is probably because add and lea assembly instructions,but why use different instructions? I'm not very clear about it.

So,if we must prevent coding in this style? like iNum = (iNum++ % Alphabet).

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Ben-xue
  • 103
  • 1
  • 6
  • Does the line `Data data = {0};` compile? – IrAM Dec 18 '20 at 09:11
  • Yes, that initialises the first (and only) field to 0. It's ugly for obvious reasons, but was required with older compilers. – gnasher729 Dec 18 '20 at 09:12
  • @gnasher729 also older compilers should complain about `Data` as there is no such type in that code. This is not C++ where that woule be legal. BTW: I can't see anything ugly about it. – Gerhardh Dec 18 '20 at 09:17
  • The last sentence in the question is the right conclusion. The code behaviour is undefined. – Weather Vane Dec 18 '20 at 09:20

2 Answers2

0

Your second example is undefined behaviour. The same object (data.iNum) is modified twice without intervening sequence point. Anything can happen, including your app crashing, including your app only crashing when you deliver it to a paying customer who will sue you for millions.

PS. No, the same expression did not produce different results. Two very different expressions with some insignificant similarity produced different results. And since the same will happen when your code runs on a computer with an ARM processor, it has nothing to do with the assembly instructions. Assembly instructions don't come into this at all.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

Your code is one big undefined behaviour. But if we change it to make it defined:

#include <stdio.h>

#define Alphabet    26

struct Data
{
    int iNum;
    int iNum1;
};

int main()
{
    #if 1
        int iNum = 0;
        int iNum1 = 0;
        while(1)
        {
            iNum1 = (iNum++ % Alphabet);
            iNum = iNum1;
            printf("%d\n",iNum);
        }
    #else
        struct Data data = {0};
        while(1)
        {
            data.iNum1 = (data.iNum++ % Alphabet);
            data.iNum = data.iNum1;
            printf("%d\n",data.iNum);
        }
    #endif

    return 0;
}

The compiler will notice that the code in both cases will simply print zeroes: https://godbolt.org/z/Tn157h

0___________
  • 60,014
  • 4
  • 34
  • 74