Lokesh Meher
Lokesh Meher

Reputation: 447

Is there a reasonable fix for "warning: control reaches end of non-void function [-Wreturn-type]"?

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

Answers (4)

Chris Jefferson
Chris Jefferson

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 exception
  • call abort, 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

Lassie
Lassie

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

Sergey Kalinichenko
Sergey Kalinichenko

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

NathanOliver
NathanOliver

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

Related Questions