-6

I am confused with the input and output, can anyone tell me why I get such output.

#include<iostream>
#include<stdlib.h>
using namespace std;

int main()
{
    int ival, oddcnt(0), evencnt(0);
    while (cin >> ival) {
        switch (ival) {
        case 1, 3, 5, 7, 9:
            oddcnt++;
            break;
        case 2, 4, 6, 8, 10:
            evencnt++;
            break;
        }
    }
    cout << "Quantity of odd number:" << oddcnt << "\n"
        << "Quantity of even number:" << evencnt << endl;
    system("pause");
    return 0;
}

This is the result I get: Input:1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 9 9 10 10 10 EOF Output:Quantity of odd number:2 Quantity of even number:3 enter image description here

Higher
  • 3
  • 1
  • 4
  • 3
    I can't access your image with the output from my workplace, can you please write it down? – Ignacio Alorre Mar 06 '17 at 06:11
  • 1
    What makes you think that `case 1, 3, 5, 7, 9:` is valid c++? – πάντα ῥεῖ Mar 06 '17 at 06:12
  • I'm guessing its only checking the 9's and 10's. [Some post on the comma operator](http://stackoverflow.com/questions/54142/how-does-the-comma-operator-work) – JGroven Mar 06 '17 at 06:14
  • switch case statements syntax is invalid..that is not correct formatted... – Vinoth Raj Mar 06 '17 at 06:14
  • How did you compile that stuff and got it running? http://coliru.stacked-crooked.com/a/74f9ab15593402d9 – πάντα ῥεῖ Mar 06 '17 at 06:16
  • Wrong duplicate! In standard C++ this cannot be parsed a comma operator. – AnT Mar 06 '17 at 06:16
  • @AnT You're able to edit duplicates for now. – πάντα ῥεῖ Mar 06 '17 at 06:18
  • Indeed, I am a beginner learning C++, and this program is an exercise in my book, C++ Primer(fifth edition). In the exercise, I was instructed to find the error of such a problem, I know the comma here is bad. Out of curiosity, I type the program, and try to compile it. Amazingly the compile didn't fail, thus I tried to give some input and see the result. Thanks for all your advice. – Higher Mar 06 '17 at 09:13

4 Answers4

4

This usage of comma in case label is illegal in standard C++. It is simply grammatically incorrect. A conforming compiler must issue a diagnostic message in response to this code, even if it accepts it somehow.

There might (or might not) be some intricate details involved.

  • In the original C++98 language comma operator was prohibited form being used in case label. It was "blocked" by two different parts of language specification:

    Firstly, the grammar of constant-expression does not allow top-level comma operators in constant expressions. Grammatically, a comma operator can only appear in constant expressions enclosed in ().

    Secondly, C++98 specification explicitly prohibited comma operator in constant expressions at any level of nested () (see 5.19/1).

    (This was basically identical to C language requirements.)

  • However, C++11 made some changes: it allowed comma operator in constant expressions. Yet, the grammar was left unchanged. This means that comma operator is now allowed in constant expressions, but only when enclosed in (). E.g. starting from C++11 you can use

    case (1, 3, 5, 7, 9):
    

    which is an ordinary application of comma operator. It makes the whole thing equivalent to

    case 9:
    

Meanwhile, your

    case 1, 3, 5, 7, 9:

remains illegal in C++ to this day. If your compiler supports it somehow, it must be a language extension implemented by your compiler. Consult your compiler documentation to figure out what it means.

Judging by the output you got, your compiler sees case 1, 3, 5, 7, 9: as equivalent to case (1, 3, 5, 7, 9): and thus equivalent to case 9:. That explains the output. The program simply counts 9s and 10s in the input. You've got two 9s and three 10s.

See also:
Is the comma operator allowed in a constant-expression in C++11?
Why was the restriction on the comma operator being in a constant expression removed in C++11?

AnT
  • 302,239
  • 39
  • 506
  • 752
  • Well, as mentioned in the OP the compiler took that, and produced some output? Are you sure that dupe was wrongly applied here? – πάντα ῥεῖ Mar 06 '17 at 06:21
  • I like more your case (1, 3, 5, 7, 9): solution than my answer. Can't say you have 215K for nothing :) – Ignacio Alorre Mar 06 '17 at 06:22
  • [http://stackoverflow.com/questions/42618651/comma-in-switch-case] _italic_ **bold** `code` Your explanation makes sense here. At first, considering the low precedence the comma is, I can't figure out why it didn't count the number of 1 and 2. It's fun to try a wrong program which can run somehow, I think. Thanks for your explanation. – Higher Mar 06 '17 at 09:22
2

You can try this inside the switch instead:

switch (ival) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 9:
     oddcnt++;
     break;

    case 2:
    case 4:
    case 6:
    case 8:
    case 10:
     evencnt++;
     break;
}
Ignacio Alorre
  • 6,715
  • 8
  • 54
  • 83
  • 1
    Or they can discard the `switch` and use the modulus operator. `ival %2` makes a great even/odd detector. – user4581301 Mar 06 '17 at 07:26
  • yes, actually your answer would be better and shorter. But I just wrote how to make a switch that works in the way he was trying to – Ignacio Alorre Mar 06 '17 at 07:28
0
switch (var) {
    case value1: /* ... */ break;
    case value2: /* ... */ break;
    /* ... */
}
Abhishek Aryan
  • 19,503
  • 8
  • 48
  • 62
0
 switch (ival) {
        case 1, 3, 5, 7, 9:
            oddcnt++;
            break;
        case 2, 4, 6, 8, 10:
            evencnt++;
            break;
        }

case 1, 3, 5, 7, 9: This type of switch statement leads to syntax error but in your case it did not.

Syntax errors(on compiler gcc version 5.4.0 (GCC)):

error: expected ‘:’ before ‘,’ token  
       case 1, 3, 5, 7, 9:
             ^
error: expected ‘:’ before ‘,’ token
     case 2, 4, 6, 8, 10:
           ^
error: expected primary-expression before ‘,’ token

Nevertheless you can try the following switch case:

switch (ival) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
            oddcnt++;
            break;
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
            evencnt++;
            break;
        }
Liju Thomas
  • 1,044
  • 5
  • 18
  • 24