0

I am working on an Ingenico's EDC terminal. The below code was existing from previous implementation. While debugging I came across this block of code which I am facing difficulty in understanding.

short bankPEM = 0;
//bankPEM = 41; //Chip
bankPEM = 17; //Swipe
//bankPEM = 801; //Fallback

switch(bankPEM)
{
    case 021: cout<<"021"; break; //Swipe
    case 051: cout<<"051"; break; //Chip
    case 801: cout<<"801"; break; //Fallback
    default: cout<<"Default"; break;
}

bankPEM is a short variable. I found below exection observation:

  1. When it contains 41, case 051 is executed.
  2. When it contains 17, case 021 is executed.
  3. When it contains 801, case 801 is executed.

I expected the code to executed default case for number 1 & 2. Can anyone show some light in this case.

I am also converting the code to assembly language. I will share my understanding after debugging the assembly code.

Thanks in advance.

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
pkthapa
  • 1,029
  • 1
  • 17
  • 27
  • 3
    [Octal literal](http://en.cppreference.com/w/cpp/language/integer_literal) –  Apr 26 '17 at 09:53
  • 1
    It is octal...... – LPs Apr 26 '17 at 09:53
  • 1
    I've removed the assembly tag for the question, as standing, has nothing to do with assembly. You can re-add it later if needed. Remember that the assembly tag always goes with a specific architecture tag (e.g. x86-64, arm, mips, ...) – Margaret Bloom Apr 26 '17 at 09:56
  • Possible duplicate of [Using C am I right in thinking that literals beginning with multiple zeros are considered octal?](http://stackoverflow.com/questions/20621405/using-c-am-i-right-in-thinking-that-literals-beginning-with-multiple-zeros-are-c) – Johan Apr 26 '17 at 10:02

3 Answers3

5

Referring to c standard

6.4.4.1 Integer constants

A decimal constant begins with a nonzero digit and consists of a sequence of decimal digits. An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only. A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of the decimal digits and the letters a (or A) through f (or F) with values 10 through 15 respectively.

Emphasis mine

As the code shown seems/is you can also refer to c++14

2.13.2 Integer literals

An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value. An integer literal may have a prefix that specifies its base and a suffix that specifies its type. The lexically first digit of the sequence of digits is the most significant. A binary integer literal (base two) begins with 0b or 0B and consists of a sequence of binary digits. An octal integer literal (base eight) begins with the digit 0 and consists of a sequence of octal digits. A decimal integer literal (base ten) begins with a digit other than 0 and consists of a sequence of decimal digits. A hexadecimal integer literal (base sixteen) begins with 0x or 0X and consists of a sequence of hexadecimal digits, which include the decimal digits and the letters a through f and A through F with decimal values ten through fifteen. [ Example: The number twelve can be written 12, 014, 0XC, or 0b1100. The literals 1048576, 1’048’576, 0X100000, 0x10’0000, and 0’004’000’000 all have the same value. — end example ]

Emphasis mine

Community
  • 1
  • 1
LPs
  • 16,045
  • 8
  • 30
  • 61
3

The two numbers 021 and 051 are written in octal form. If you convert them into decimal form you will get:

21 (base 8) = 1 * 8^0 + 2 * 8^1 = 1 + 16 = 17 (base 10)
51 (base 8) = 1 * 8^0 + 5 * 8^2 = 1 + 40 = 41 (base 10)

So, I think you see now why when bankPEM is 17, case 021 is executed and when it is 41, case 051 is executed.

I don't understand though why the person who implemented the code decided to write the switch cases like this (it isn't even consistent because the 3rd case has a number in base 10).

Valy
  • 573
  • 2
  • 12
1

The problem is preceding zero in case declaration preceding zero make complier to think it's an octal number 021 therefore 17 base 10 = 21 base 8 hence the execution of of case 021 : same goes for 41 base 10 = 51 base 8.

 short bankPEM = 0;
//bankPEM = 41; //Chip
bankPEM = 17; //Swipe
//bankPEM = 801; //Fallback



switch (bankPEM) {
    case 021: cout << bankPEM << " " << 021;

        break; //Swipe
    case 051: cout  << bankPEM << " " << 051;
        break; //Chip
    case 801: cout << "801";
        break; //Fallback
    default: cout << "Default";
        break;
}

I hope this helps.