我有一些代码简化如下:
#include <iostream>
#include <string>
enum En
{
one,
two,
three
};
auto get_str(int n, En en)
{
if (n > 0)
{
return std::to_string(n);
}
switch (en)
{
case one:
return std::string("one");
case two:
return std::string("two");
case three:
return std::string("three");
}
}
int main()
{
auto str = get_str(3, two);
std::cout << str << '\n';
}
参见编译器资源管理器。
当我使用 GCC 14.2 或 13.3.0(带有或不带有-Wall -Wextra
)进行编译时,它会抱怨get_str
功能:
warning: control reaches end of non-void function [-Wreturn-type]
。
Clang 15.0 及以上版本-Wall -Wextra
不会发出任何警告。VS17.10 也会抱怨:warning C4715: 'get_str': not all control paths return a value
。
是什么导致 Clang 不同意?绕过 s 的路径是什么return
?
所有编译器都有自己的正确方式。相关措辞在 [dcl.enum] p8中:
对于您的代码来说,这意味着:
En
,则它的值可能是En(3)
,它不是枚举器one
two
、 和 中的任何一个three
。这是因为可以存储的最小宽度整数three
有两位,因此可以表示0
、1
、2
和3
。此外,标准明确指出,拥有这种“无枚举器值”是可能的。four
,仍可能会有更多值,因为标准仅规定了该“假设整数”的最小宽度。当 GCC 警告你时,这是正确的。如果
En(3)
传递给get_str
,控制流就会流出函数末尾,并且会出现未定义的行为。当其他编译器没有警告你时,它们也是正确的。标准不要求在这种情况下发出警告。
这里有几种可能的解决方法,可以消除警告:
std::unreachable()
到函数的末尾。default:
案例并返回或致电std::unreachable()
那里。