Search code examples
c++gcccompiler-warnings

warning: control reaches end of non-void function [-Wreturn-type] removed when declaring method inline


With this code

enum EnumTypes
{
    one,
    two
};

int enum_to_int(EnumTypes enum_type)
{
    switch(enum_type)
    {
        case one: return 1;
        case two: return 2;
    }
}

I get the following warning:

: In function 'int enum_to_int(EnumTypes)': :14:1: warning: control reaches end of non-void function [-Wreturn-type] 14 | }

, which I understand is a valid warning since enum_type could have some other value stored than one and two.

However, if I mark the method as inline as the following, the warning disappears.

enum EnumTypes
{
    one,
    two
};

inline int enum_to_int(EnumTypes enum_type)
{
    switch(enum_type)
    {
        case one: return 1;
        case two: return 2;
    }
}

Should there not be a warning if function is marked inline?


Solution

  • In contrast to a non-inline function with external linkage, an inline function or a function with internal linkage (static) is guaranteed to be defined in every translation unit (odr-)using the function (or else the program is ill-formed).

    The compiler is therefore just being "lazy" and doesn't emit a definition for the inline function, since you don't (odr-)use it in the translation unit.

    If you (odr-)use it in any way, it will be emitted and the checks wont be skipped. It is enough to take a pointer to the function:

    auto ptr = &enum_to_int;
    

    And then the warning will appear again.


    It is probably reasonable that the compiler doesn't check the function for such issues in a translation unit where the definition doesn't need to be emitted. It is guaranteed that the program either doesn't use the function at all, in which case the problem doesn't really matter, or it is (odr-)used in another translation unit and the warning will be produced there.

    Checking it in all translation units would probably just be wasted time.