在 C++ 的非 void
函数中,程序执行流程到达函数末尾。
在本例中,选手为了少写一个字母,将本应返回 void
的函数写成返回 int
。尽管该函数的返回值从未被使用过,但调用该函数仍然触发未定义行为,可能导致程序崩溃或输出不正确的结果。
int dfs(int u, int p, int c)
{
color[u] = c;
for (int v: G[u])
if (v != p)
dfs(v, u, c ^ 1);
/* no return value here */
}
在本例中,选手在函数中只处理了 的情况。对于其他情况,选手认为该函数的返回值不会被使用,因此未返回值。然而,对于 C++,只要以其他的 值调用该函数,即触发未定义行为 (无论返回值是否被使用过)。(对于 C 来说选手的想法是正确的。)
int tianshi(int n)
{
switch (n) {
case 1: return 114;
case 2: return 514;
case 3: return 1919;
case 4: return 810;
}
/* no return value here */
}
int main()
{
int n;
cin >> n;
int r = tianshi(n);
if (n <= 4 && n >= 1)
cout << r << '\n';
else
cout << "bad input\n";
return 0;
}
在编译时打开 -Wreturn-type
(被 -Wall
包含,在较高版本的 GCC 中默认打开)。
警告信息示例:
t.cc:13:1: 警告:在有返回值的函数中,控制流程到达函数尾
[-Wreturn-type]
void
。assert
或者 abort
使得程序在输入不满足约束时崩溃,从而尽早发现错误。main
函数执行到函数尾 (此时将默认返回 0
)。但是,不建议依赖该行为,这样可以兼容较旧的 C++ 标准,同时提醒自己 int
函数总是需要返回值。int tianshi(int n)
{
switch (n) {
case 1: return 114;
case 2: return 514;
case 3: return 1919;
case 4: return 810;
}
abort(); /* unexpected input */
}
int main()
{
int n;
cin >> n;
if (n <= 4 && n >= 1)
cout << tianshi(n) << '\n';
else
cout << "bad input\n";
return 0;
}