Control may reach end of non-void function switch statement - c++

I tried to do a simple calculator. Don't understand why i'm getting the warning that "Control may reach end of non-void function." for the f() function. Any suggestions?
Here is my code:
#include <iostream>
using namespace std;
int f(int a, int b, int i){
switch(i){
case 1: return a+b;
case 2: return a-b;
case 3: return a*b;
case 4: return a/b;
case 5: return a%b;
}
}
int main(){
char Continue='y';
int a,b,i;
cout<<"1.Add"<<endl<<"2.Subtract"<<endl<<"3.Multiply"<<endl<<"4.Divide"<<endl<<"5.modulus"<<endl;
do{
cout<<"Enter two numbers:"<<endl;
cin>>a;
cin>>b;
cout<<"Enter the number of what kind of caculation you want to do";
cin>>i;
cout<<f(a,b,i);
cout<<"Press y to continue/n";
cin>>Continue;
}while(Continue=='y');
}

Because if i is neither 1, 2, 3, 4, 5, then the execution passes over the entire switch statement completely, and there is no explicit return from a function that should return an int.

you need to add some type of default label into your switch statement, general syntax is as follows
switch(value)
{
case 0 :
//do something
break;
case 1:
break;
//// add any case as needed
default : // this would be the line you're missing
break;
}
non void means it doesn't return anything, it's the same thing as witting a function that returns a something, but instead you skip that part entirely
tldr you're esentially doing this
int non_void()
{
//do stuff but not return anything
}

Related

C++ / warning: control reaches end of non-void function [-Wreturn-type]

I am just a beginner today and trying to learn desktop programming with C++. And I am confused that why doesnt this work:
The code:
int math(int opt, int x, int y){
switch(opt){
case 1:
return x + y;
break;
case 2:
return x - y;
break;
case 3:
return x * y;
break;
case 4:
return x / y;
break;
default:
break;
}
}
The use:
cout << to_string(math(1,1,2)));
The error:
main.cpp: In function ‘int math(int, int, int)’:
main.cpp:38:1: warning: control reaches end of non-void function [-Wreturn-type]
38 | }
| ^
Thank you all,
as I understand:
break; after return is extra because will be never executed
need to return something in all cases(i.e. if opt is bigger than 5)
So this works now:
int math(int opt, int x, int y){
switch(opt){
case 1:
return x + y;
case 2:
return x - y;
case 3:
return x * y;
case 4:
return x / y;
default:
return 0;
}
}
A function that has any return type other than void needs to reach a return statement with the correct value type specified.
A function is built like this: returnType name(type parameterName, ...){}
If the return type is (as in your case) an int, the path of execution must reach a return foo; statement, where foo is, or convertible to, an int.
int math(int opt, int x, int y){
switch(opt){
case 1:
return x + y;
case 2:
return x - y;
case 3:
return x * y;
case 4:
return x / y;
default:
throw std::invalid_argument("math parameter opt out of range!");
}
}
Also, any code after reaching a return is not executed, so the break; statements are extraneous.
The problem is, if you pass "invalid" opt value, default case gets selected, and your function returns nothing. So one solution would be to decide what to return if you pass invalid opt.
You should fix your problem like this:
enum class Opt { PLUS, MINUS, TIMES, DIVIDED };
int math(Opt opt, int x, int y) {
switch(opt){
case Opt::PLUS:
return x + y;
case Opt::MINUS:
return x - y;
case Opt::TIMES:
return x * y;
case Opt::DIVIDED:
return x / y;
}
// it is important to not have default: case
// above because now compiler will issue warning,
// you add new values to Opt.
// below line should never be reached, so value doesn't matter,
// but it's needed to disable warning on some compilers.
return 0;
}
// test
int main() {
return math(Opt::PLUS, 1, 2); // exit code 3
}
Using enum class has the benefit, that if you want to shoot yourself into foot by passing random integer as opt, you have use an explicit cast to convert the integer into an enum class value.

how to replace a value of a variable inside code from user input?

i am trying to add a developer mode in my program. since duty of car defers every month,i want give my user permission to change every single variables in my program alike duty lccost yen2taka freight
#include <iostream>
using namespace std;
class A
{
public:
int carbid,duty;
void Input()
{
cout<<"please insert the car price you want to bid for(in yen): ";
cin>>carbid;
cout<<"duty of the car: ";
cin>>duty;
}
int Exportcost()
{
int exportcost;
int servicechrg=10;
int freight=20;
exportcost=servicechrg+freight+carbid;
return exportcost;
}
int Yen2taka()
{
int yen2taka;
int taka2dollarrate=10;
int dollar2yen=1;
yen2taka=((Exportcost())/dollar2yen)*taka2dollarrate;
return yen2taka;
}
int Importcost()
{
int importcost;
int lccost=10;
int cnfcost=20;
importcost=lccost+cnfcost;
return importcost;
}
int Totalcosting()
{
int total;
int myprofit=10; //80000
total=myprofit+Importcost()+Yen2taka();
cout<<total;
return total;
}
void summary()
{
cout<<
}
};
int main()
{
x:
A ob;
ob.Input();
ob.Exportcost();
ob.Yen2taka();
ob.Importcost();
ob.Totalcosting();
int ch;
cout<<"press 1 to see the summery of the costing or 2 to restart costing again"<<endl;
cin>>ch;
switch(ch)
{
case 1:
ob.summary();
break;
case 2:
goto x;
}
}
At first, you should collect these parameters in a separate class:
class Configuration // maybe you find a better name...
{
int m_servicechrg = 10; // default
int m_freight = 20;
// ...
public:
int servicechrg() { return m_servicechrg; }
void servicechrg(int value); { /* check some limits? */ m_servicechrg = value; }
int freight() { return m_freight; }
void freight(int value); { /* check some limits? */ m_freight = value; }
// ...
};
// will allow you to do:
// C c; std::cout << c;
ostream& operator<<(ostream& s, Configuration const& c)
{
// which ever formatting is appropriate...
s << c.servicechrg() << ' ' << c.freight();
return s;
}
The setters could alternatively return bool to indicate invalid values.
Now you can use this class within main:
Configuration c;
A a;
int cost = a.exportCost(c); // you'd have to adjust signatures...
int value;
switch(ch)
{
case 4:
if(stc::cin >> freight) // catches invalid user input!
// one ALWAYS should do, otherwise you might end up in
// your program not working any more
{
c.freight(value);
// or, if you have:
if(!c.freight(value))
{
// some appropriate error message
// (it's better not to output in the setter, you are more flexible this
// way – maybe you want different messages at different occasions?)
}
}
else
{
// appropriate error handling
}
break;
default:
// handling invalid user input
// again, you always should; but stream state is not in error state,
// so you just can print appropriate error message
break;
}
See this answer for how to correctly handle stream errors.
If you wonder about the differences in error handling: First case is met if user enters non-numerical input, such as ss, second case, if input is numerical, but out of valid range (77).
Now if you don't want to pass the configuration as parameter all the time, you could make a global variable from (but careful, there are some dangers with global variables, use them as sparely as possible) or implement the singleton pattern.
Side notes: goto can be a fine tool sometimes, but it is a dangerous one (and the label's name x isn't a good one, prefer a name that clearly shows intention, such as REENTRY_POINT, LOOP_START, ...). If you can get along without unreasonable effort, prefer such variants:
bool isRunning = true;
do
{
// ...
case 2:
isRunning = false;
break;
}
while(isRunning);
Sure, an additional variable, an additional check; unfortunately, you cannot use break to exit a (pseudo-) endless loop (for(;;)) (but don't apply this pattern for nested loops, then it gets more and more unreadabla – and ineffcient: bool isExit = false; for(int i = 0; !isExit && i < n; ++i) { for(j = 0; j < n; ++j) { isExit = true; break; } } – see what I mean?). A variant might be:
for(;;)
{
switch(ch)
case 1:
// ...
//break; <- replace
continue;
case 2:
//
break;
} // end of switch
break; // break the surrounding for(;;) loop
}
But that's not really nice either.
A pretty nice variant allowing to exit the loop in the given case, as there isn't anyhting to do afterwards:
for(;;)
{
switch(ch)
{
case 2:
// maybe yet some cleaning up here
return 0;
default:
// ...
break;
}
}
Drawback: The function's exit point possibly is deeply nested inside the code.
There are yet other tricks to allow this pattern, like packing sub-sections of code in a lambda having a return inside and call that one directly. But that now really starts going beyond the scope...
Finally, if you insist on goto, my variant would rather be:
for(;;)
{
switch(ch)
{
case 2:
// ...
goto LOOP_EXIT;
default:
// ...
break;
}
}
LOOP_EXIT:
return 0; // e. g. main
(void)0; // if there isn't anything to do in the function any more
// (labels require an instruction afterwards!)
There won't be a hidden loop now and it is more obvious what you actually are doing. Currently, not really an issue, but if your code grows, the hidden loop gets more and more difficult to spot.
In such cases, I clearly mark the gotos so that another coder can immediately spot the critical code points:
///////////////////////////////////////////////////
// possibly some comment why applying this pattern
goto SOME_LABEL;
///////////////////////////////////////////////////
One could do the same with deeply nested function exit points (return).

c++ switch [Error] 'x' cannot appear in a constant-expression

im trying to execute this script its for my university
int main()
{
int x;
double y;
Provo:
cout<<"Vlera e X: ";
cin>>x;
switch(x)
{
case ((x)<(0.9)):
y=x*x;
break;
case (x==0.9):
y=2*x;
break;
case 'x>0.9':
y=x-3;
break;
}
cout<<"\n\n";
return 0;
}
this is teh code and the error is:
17 10 ....\Untitled1.cpp [Error] 'x' cannot appear in a constant-expression
someone help please?
I think you have misunderstood how to use the switch statement. switch is used to branch your code based on the condition, in your case x, taking different integral values. It is not suitable for use with double values like you do.
A correct switch expression would look like:
switch(x)
{
case 1:
y=x*x;
break;
case 2:
case 3:
case 4:
y=2*x;
break;
case 5:
y=x-3;
break;
}
To accomplish what you want, use if else instead, for example:
if (x < 0.9) {
y=x*x;
else if(x == 0.9) {
y=2*x;
} else {
y=x-3;
}
However, comparing floating point values for equality is a bad idea. It is usually better to do something like:
double epsilon = <some small value>;
if (x < 0.9-epsilon) {
y=x*x;
else if(x > 0.9+epsilon) {
y=x-3;
} else {
y=2*x;
}

C++ program crashes in the while loop when asked to use random number generator

So I am trying to make a program which will generate random basic mathematical questions like addition, subtraction, etc.
While I am trying to generate division questions I made a do-while loop which runs until the prerequisite is met for division quesions.
But for some reason when I ask it to generate 20 division questions with none with remainder it always crashes.
Please help
Here's the code
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int correct,total,MAXVAL;
const char oper[4]={'/','/','/','/'};
typedef struct data{
int first,second;
char operation;
}data;
data datagenerator(){
data newData;
newData.first= (rand()%MAXVAL);
newData.operation=oper[rand()%4];
newData.second=(rand()%MAXVAL);
return newData;
}
bool corrector(data newData){
bool isture=false;
switch(newData.operation){
case '/':
if((newData.first%newData.second)==0){
isture=true;
}
break;
case '*':
isture=true;
break;
case '+':
isture=true;
break;
case '-':
isture=true;
break;
}
return isture;
}
void quizer(){
system("CLS");
for(int counter=1;counter<=total;counter++){
cout<<"Q"<<counter<<": ";
data newData;
do{
newData=datagenerator();
}while(!corrector(newData));
cout<<newData.first<<newData.operation<<newData.second<<"\n";
}
cout<<"\nYou got "<<correct<<"/"<<total<<"correct\n";
}
int main(){
//srand((unsigned)time(0));
char x;
cout<<"How many questions do you want?"<<endl;
cin>>total;
cout<<"Enter the maximum value\n";
cin>>MAXVAL;
cout<<"Are you ready?\n";
cin>>x;
quizer();
system("PAUSE");
return 0;
}
You need to check for a division by 0.
bool corrector(data newData){
bool isture=false;
switch(newData.operation){
case '/':
if(newData.second == 0) {
break;
}
if((newData.first%newData.second)==0){
isture=true;
}
...
Your generating a 0 as a second number and then trying to use it to divide by a number.
you can put a check like this
if(newData.second == 0) {
return false;
}
Your problem lies right on line 17 and 19. You are dividing by 0, assuming you are setting the value on MAXVAL to 0 when it asks you. With modulo division you need to be careful with that.

C++ Stack Implementation (not working right)

Here's the previous thread where I got help with this same lab. My stack is misbehaving, to say the least, when I add an item to stack, to print out later, it doesn't seem to add right. I always print out plus'(+), not matter if I enter another operand(*,/,+).
I am using a stack to convert a, user inputed, infix express to postfix. It seems to work fine except printing out the operands in the stack at the end.
#include <iostream>;
#include <vector>
using namespace std;
class DishWell{
public:
char ReturnFront(){
return Well.front();
}
void Push(char x){
Well.push_back(x);
}
void Pop(){
Well.pop_back();
}
bool IsEmpty(){
return Well.empty();
}
private:
vector<char> Well;
};
bool Precidence(char Input, char Stack){
int InputPrecidence,StackPrecidence;
switch (Input){
case '*':
InputPrecidence = 4;
break;
case '/':
InputPrecidence = 4;
break;
case '+':
InputPrecidence = 3;
break;
case '-':
InputPrecidence = 3;
break;
case '(':
InputPrecidence = 2;
break;
default:
InputPrecidence = 0;
}
switch (Stack){
case '*':
StackPrecidence = 4;
break;
case '/':
StackPrecidence = 4;
break;
case '+':
StackPrecidence = 3;
break;
case '-':
StackPrecidence = 3;
break;
case '(':
StackPrecidence = 2;
break;
default:
StackPrecidence = 0;
}
if(InputPrecidence>StackPrecidence) return true;
else return false;
}
int main(int argc, char** argv) {
DishWell DishTray;
char Input;
bool InputFlag;
InputFlag = true;
cout<<"Enter Input, invalid input will terminate"<<endl;
while(InputFlag){
cout<<"Input: ";
cin>>Input;
cout<<endl;
if((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||Input>='0'&&Input<='9')))//If Digit or Number
cout<<Input;
if((Input=='*'||Input=='/'||Input=='+'||Input=='-')){//if operand
if(DishTray.IsEmpty())
DishTray.Push(Input);
else if(Precidence(Input,DishTray.ReturnFront()))
DishTray.Push(Input);
else if(!Precidence(Input,DishTray.ReturnFront()))
cout<<"Output: "<<Input<<endl;
}
else if(!((((Input>='a'&&Input<='z')||(Input>='A'&&Input<='Z'))||(Input>='0'&&Input<='9')))||((Input=='*'||Input=='/'||Input=='+'||Input=='-')))//if not digit/numer or operand
InputFlag = false;
}
int counter = 0;
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnFront()<<endl;
DishTray.Pop();
}
return 0;
Thank you, Macaire Bell
Your loop calls front(), but then calls pop_back(). This will always return the first element in the vector, until all elements are popped, since you are never erasing the front element. Your ReturnFront() method should probably be:
char ReturnBack(){
return Well.back();
}
And then your loop at the end:
while(!DishTray.IsEmpty()){
counter++;
cout<<counter<<" Element "<<DishTray.ReturnBack()<<endl; // will return last element
DishTray.Pop(); // actually pop the element printed
}
When you're working with a stack, you usually want to be able to see the value on the top of the stack. Your class only allows the very first item pushed (i.e. the bottom of the stack) to be visible. Your ReturnFront() should probably return Well.back() and perhaps it should be called something like ReturnTop().
Wouldn't you want to see the value returned from pop_back() instead if discarding it as you're currently doing?