47

I have the following error in my Calculator code and do not understand how to correct it. Please any advice would be helpful.

ERROR: error: jump to case label [-fpermissive]| error:crosses initialization of 'int sum'| error: 'exit' was not declared in this scope|

CODE:

#include <iostream>
#include <cmath>
using namespace std;         
void display_menu(); 
int get_menu_choice();
void get_two_numbers(int &a, int &b);
int add(int a, int b);
int subtract(int a, int b);


int main()
 {
 int choice;

  do
   {
    display_menu();
    choice = get_menu_choice();
    int x, y;
    switch (choice)
    {
        case 1: get_two_numbers(x, y);
                int sum = add(x, y);
                cout << x << " + " << y << " = " <<  sum << endl;
                break;
        case 2: get_two_numbers(x, y);
                int diff = subtract(x, y);
                cout << x << " - " << y << " = " <<  diff << endl;
                break;
        default:;
    }

     } while (choice != 3);

     cout << "Good bye...now." << endl;

     return 0;
       }


 void display_menu()
  {
   cout << endl;
   cout << "Simple Calculator Menu" << endl;
   cout << "----------------------" << endl;
   cout << " 1. Addition (+) " << endl;
   cout << " 2. Subtraction (-) " << endl;
   cout << " 3. Quit to exit the program" << endl;
   cout << endl;
  }

 int get_menu_choice()
  {
   int choice;
   cout << "Enter your selection (1, 2, or 3): ";
   cin >> choice;

  while(((choice < 1) || (choice > 3)) && (!cin.fail()))
   {
    cout << "Try again (1, 2, or 3): ";
    cin >> choice;
    }
  if (cin.fail())
    {
      cout << "Error: exiting now ... " << endl;
      exit(1);
     }
   return choice;
    }

 void get_two_numbers(int &a, int &b)
  {
    cout << "Enter two integer numbers: ";
    cin >> a >> b;
  }


 int add(int a, int b)
  {
   return (a + b);
  }

 int subtract(int a, int b)
  {
    return (a - b);
  }
Paul
  • 139,544
  • 27
  • 275
  • 264
user3555274
  • 471
  • 1
  • 4
  • 3
  • 4
    just change int sum = add(x, y); to int sum; sum=add(x.y); That has to be the worse warning ever. – J Decker Aug 02 '17 at 00:29

3 Answers3

93

You are declaring new variables inside a case statement without creating an enclosing scope:

switch (choice)
{
    case 1: get_two_numbers(x, y);
            //* vv here vv *
            int sum = add(x, y);
            //* ^^ here ^^ */
            cout << x << " + " << y << " = " <<  sum << endl;
            break;
    case 2: get_two_numbers(x, y);
            //* vv here vv */
            int diff = subtract(x, y);
            //* ^^ here ^^ */
            cout << x << " - " << y << " = " <<  diff << endl;
            break;
    default:;
}

Here's how to fix it:

switch (choice)
{
    case 1:
        {
            get_two_numbers(x, y);
            int sum = add(x, y);
            cout << x << " + " << y << " = " <<  sum << endl;
        }
        break;
    case 2:
        {
            get_two_numbers(x, y);
            int diff = subtract(x, y);
            cout << x << " - " << y << " = " <<  diff << endl;
        }
        break;
    default:
        break;
}

Of course, the exact formatting of brackets and indentation is up to you.

kfsone
  • 23,617
  • 2
  • 42
  • 74
  • Will there be any problem if I put the break statement inside the curly braces? – Vishal Sharma Jun 15 '20 at 03:46
  • @VishalSharma Putting the break inside the braces is fine, but can lead to readability issues/bugs, by guaranteeing there is an unconditional break that prevents "fallthrough" to another case. Interpret it this way: `case 2: { do some things }; whatever happens stop now; default: ...` – kfsone Sep 08 '20 at 22:37
  • Sorry but I didn't understand when exactly it causes bugs? – Vishal Sharma Sep 10 '20 at 16:46
  • Think of it this way, there are three versions of `break`: case-break, for-break and while-break. So what do you think the output of this code would be: https://gcc.godbolt.org/z/11v9do – kfsone Sep 11 '20 at 17:08
  • if there are loops within loops along with the switch cases, I think a break will get the execution out from the topmost frame on that stack of switch/while/for loops..your example seems to follow this as well and I'm still missing your point. – Vishal Sharma Sep 11 '20 at 17:28
  • @VishalSharma There's a high-cognitive load with this construct, and in my 25 years experience with C++ I've found that people routinely get this wrong. The anonymous block/scope, mixed loop constructs, and the fact that switch statements are comparatively rare, all tend to make it easy to miscount {/}s, or etc. https://gist.github.com/kfsone/24ad2dd9334ad38fd7d0d261dcec2eeb – kfsone Sep 14 '20 at 01:34
25

A "case" of a switch doesn't create a scope, so, as the error says, you're jumping over the initialization of "sum" if the choice isn't 1.

You either need to declare sum and diff outside the switch, or create blocks with { } for each of the cases.

Andrew McGuinness
  • 2,092
  • 13
  • 18
5

You should be declaring variables outside the switch statement and not inside a case. In particular sum and diff are problematic in your code. Once these variables are initialized outside the switch statement you can then set their values.

Nassim
  • 301
  • 3
  • 11
  • 3
    Because `sum` and `diff` are used only in their respective cases it is better to add a scope inside the `case`, as stated in the top-rated answer. Generally it's best to limit variable scopes to the smallest possible range. – Stefan Jan 25 '19 at 11:23