Home > Enterprise >  Missing return statement after if-else
Missing return statement after if-else

Time:10-02

Some compilers (pgi/nvc ) issue "missing return statement" warning for functions like below, while others (gcc, clang) do not issue warnings even with -Wall -Wextra -pedantic:

Is the code below legal according to the standard?

This is a minimal reproducible example of my code that gives the warning. Simplifying it to, say, just a single function removes the warning.

// test.cpp
#include <climits>
#include <cstddef>
#include <cstdint>

template<class T, std::size_t N>
class Test
{
public:

    class Inner;

private:
    using base_t = std::uint64_t;
    static constexpr std::size_t NB_ = sizeof(base_t) * CHAR_BIT;
    static constexpr std::size_t NI_ = (N   NB_ - 1) / NB_;
};

template<class T, std::size_t N>
class Test<T, N>::Inner
{
public:

    Inner() : b_{0}, j_{0} {}

    friend bool operator!= (Inner x, Inner y)
    {
        if constexpr(J_ > 0)
            return x.j_ != y.j_ || x.b_ != y.b_;
        else
            return x.b_ != y.b_;
    }

private:
    static constexpr std::size_t J_ = NI_ - 1;
    base_t b_;
    std::size_t j_;
};

int main()
{
    Test<int, 50>::Inner x, y;
    x != y;
}

Compilation:

> nvc   test.cpp -std=c  17
"test.cpp", line 31: warning: missing return statement at end of non-void function "operator!="
      }
      ^
          detected during instantiation of class "Test<T, N>::Inner [with T=int, N=50UL]" at line 42

CodePudding user response:

The C standard says this, see [stmt.return]/2:

Flowing off the end of a constructor, a destructor, or a function with a cv void return type is equivalent to a return with no operand. Otherwise, flowing off the end of a function other than main results in undefined behavior.

Your operator != does exactly that. It never flows off the end of the function since all control paths end with a return.

Hence the code is correct, and the compiler's diagnostic is wrong.

CodePudding user response:

Could those projects be set to compile as an earlier standard of C ?

Some older compilers don't like returns in the middle of code blocks (there are also those that don't like variable identifiers anywhere other than at the start of code blocks).

For those that do complain I just code as:

ret_type f(...)
{
    ret_type result = DEFAULT_VALUE; //default value defined elsewhere
    if (condition)
        result = value_1; //presumed valid ret_type value
    else
        result = value_2; //presumed valid ret_type value
    
    return result;
}
  • Related