警告:控制到达非空函数的结尾 [-Wreturn-type] 在声明方法内联时被移除

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

使用此代码

enum EnumTypes
{
    one,
    two
};

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

我收到以下警告:

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

,据我所知,这是一个有效的警告,因为 enum_type 可能存储了 onetwo.

以外的其他值

但是,如果我将方法标记为 inline 如下所示,警告就会消失。

enum EnumTypes
{
    one,
    two
};

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

如果函数被标记为内联,不应该有警告吗?

inline 不保证函数是内联的。它可能是内联的,也可能不是。我没有设法调用该函数,也没有收到警告。例如:

enum EnumTypes
{
    one,
    two
};

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

int main() {
    return enum_to_int(1);
}

结果:

<source>: In function 'int main()':
<source>:17:24: error: invalid conversion from 'int' to 'EnumTypes' [-fpermissive]
   17 |     return enum_to_int(1);
      |                        ^
      |                        |
      |                        int
<source>:7:34: note:   initializing argument 1 of 'int enum_to_int(EnumTypes)'
    7 | inline int enum_to_int(EnumTypes enum_type)
      |                        ~~~~~~~~~~^~~~~~~~~
<source>: In function 'int enum_to_int(EnumTypes)':
<source>:14:1: warning: control reaches end of non-void function [-Wreturn-type]
   14 | }
      | ^
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:17:24: error: invalid conversion from 'int' to 'EnumTypes' [-fpermissive]
   17 |     return enum_to_int(1);
      |                        ^
      |                        |
      |                        int
<source>:7:34: note:   initializing argument 1 of 'int enum_to_int(EnumTypes)'
    7 | inline int enum_to_int(EnumTypes enum_type)
      |                        ~~~~~~~~~~^~~~~~~~~
<source>: In function 'int enum_to_int(EnumTypes)':
<source>:14:1: warning: control reaches end of non-void function [-Wreturn-type]
   14 | }
      | ^
Execution build compiler returned: 1

UB只有在实际调用函数时才会触发。而且传0或者1的时候没有UB。可能是故意的,否则就没有 return。

不过,我还是希望看到警告。也算是个BUG吧。

与具有外部链接的 non-inline 函数相比,内联函数或具有内部链接的函数 (static) 保证在每个翻译单元 (odr-) 中使用函数(否则程序是 ill-formed)。

因此,编译器只是“懒惰”,不会发出内联函数的定义,因为您不会 (odr-) 在翻译单元中使用它。

如果您 (odr-) 以任何方式使用它,它将被发出并且不会跳过检查。带一个指向函数的指针就够了:

auto ptr = &enum_to_int;

然后警告会再次出现。


编译器在不需要发出定义的翻译单元中不检查函数是否存在此类问题可能是合理的。保证程序要么根本不使用该功能,在这种情况下问题并不重要,要么它在另一个翻译单元中被 (odr-) 使用,并且会在那里产生警告。

在所有翻译单元中检查它可能只是浪费时间。