Reputation: 447
I have implemented a simple templated class for a stack using linked list as such:
template <typename T>
struct Element
{
T data;
Element<T> *next;
};
template <typename T>
class Stack
{
private:
Element<T> *m_top;
public:
Stack(); // create an empty stack
void push(T value);
T pop();
T top();
bool isEmpty();
};
In the implementation of the top()
which returns the value stored in the element at the top of the stack without removing it, I am getting the following error:
warning: control reaches end of non-void function [-Wreturn-type]
I have enabled -std=c++11 -pedantic -Wall
options with g++
. Here's the top()
:
template <typename T>
T Stack<T>::top()
{
if (this->isEmpty()) // isEmpty() returns true if m_top == nullptr, false otherwise
{
std::cerr << "Stack empty!" << std::endl;
}
else
{
return m_top->data;
}
}
Since there are only two possible values- either the stack is empty or not, therefore the if-else
construct. But what do I put inside the if
clause after the std::cerr
statement to make the compiler happy and not get the warning? I cannot simply put a return;
statement as the compiler expects a value to be returned. Also if the stack is empty, there is nothing to be returned.
Additional help:
Is it a good practice to leave the compiler complaining when you know the logic of the program is right?
Upvotes: 1
Views: 1646
Reputation: 7157
You need to return something in the case:
if (this->isEmpty()) // isEmpty() returns true if m_top == nullptr, false otherwise
{
std::cerr << "Stack empty!" << std::endl;
}
You have two(ish) choices.
throw
an exceptionabort
, terminate
, or some other method which will cause your program to exit. Most compilers know that these methods never return, so they will not produce these errors.Upvotes: 2
Reputation: 858
You must either return something or throw an exception in your if
statement.
Also take note that the compiler gives this warning when it doesn't know if the non-void function will always return value.
int remainder (int n)
{
switch(n%5)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return 4;
}
}
In this function compiler gives warning because it doesn't know that n%5
is always 0, 1, 2, 3 or 4.
warning: control reaches end of non-void function [-Wreturn-type]
You can prevent that by replacing one of the cases with default.
int remainder (int n)
{
switch(n%5)
{
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
default: return 4;
}
}
Now compiler doesn't give warnings.
Upvotes: 0
Reputation: 726779
In cases like yours, when it is logically incorrect to return anything, you should throw an exception to make the program stop:
if (this->isEmpty()) {
std::cerr << "Stack empty!" << std::endl;
throw std::logic_error( "calling top when stack is empty is illegal" );
} else {
return m_top->data;
}
Upvotes: 2
Reputation: 180805
This is because you do not return anything in
if (this->isEmpty()) // isEmpty() returns true if m_top == nullptr, false otherwise
{
std::cerr << "Stack empty!" << std::endl;
}
If you enter the if statement then you output the text, exit the if statement and then hit the end of the function. You either need a return
inside the if statement or a return
at the end of the function.
If you need a control path to not return but you need the function to end then the only thing I can think of is to throw an exception. That will exit the scope and send the exception up the call stack until it reaches an acceptable exception handler.
Upvotes: 2