如果您想查明是否存在您想要的警告,只需启用所有 [使用/Wall] 并针对一小段代码进行测试。如果有警告,恭喜,你找到了。如果没有,那么运气不好,没有。
我使用.c 和.cpp 文件扩展名进行测试,以防编译器根据它正在编译的语言表现不同(果然,测试2 的行为不同)。
我的任何测试都没有抱怨过main(),因为main() 是特殊的,因为它是C 和C++ 中唯一一个在没有提供显式return 时默认返回0 的函数。
下面的所有测试都是使用 Visual Studio 2015 的编译器(即C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cl.exe)完成的,并且命令是从 VS2015 x86 Native Tools 命令提示符发出的。
如果我遗漏了任何测试用例,请发表评论让我知道。
测试
C 测试
测试 1 - 返回类型为 int 的空函数
test_warnings.c:
int main() {}
int foo() {}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(3) : error C4716: 'foo': must return a value
测试 2 - 带有 int 返回类型的函数,带有 return 没有值
test_warnings.c:
int main() {}
int foo() {
return;
}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
C:\Users\Administrator\src\test-code\test_warnings.c(4): error C4033: 'foo' must return a value
测试 3 - 具有 int 返回类型的函数,其中执行可能“脱离”函数的末尾
此测试表明这些警告还不够,因为此代码没有发出警告或错误。
test_warnings.c:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.c
test_warnings.c
c:\users\administrator\src\test-code\test_warnings.c(14) : error C4715: 'foo': not all control paths return a value
C++ 测试
测试 1 - 返回类型为 int 的空函数
test_warnings.cpp:
int main() {}
int foo() {}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(3) : error C4716: 'foo': must return a value
测试 2 - 带有 int 返回类型的函数,带有 return 没有值
test_warnings.cpp:
int main() {}
int foo() {
return;
}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
C:\Users\Administrator\src\test-code\test_warnings.cpp(4): error C2561: 'foo': function must return a value
C:\Users\Administrator\src\test-code\test_warnings.cpp(3): note: see declaration of 'foo'
测试 3 - 具有 int 返回类型的函数,其中执行可能“脱离”函数的末尾
test_warnings.cpp:
#include <stdlib.h>
#include <time.h>
int main() {}
int foo() {
int rand_num;
srand(time(0));
rand_num = rand();
if (rand_num > 1) {
return 0;
}
}
编译结果:
>cl /nologo /W0 /we4033 /we4716 /we4715 C:\Users\Administrator\src\test-code\test_warnings.cpp
test_warnings.cpp
c:\users\administrator\src\test-code\test_warnings.cpp(14) : error C4715: 'foo': not all control paths return a value
你能用C4715得到这个吗?
我重新进行了上面的测试,看看您是否可以仅使用 C4715 获得相同的行为,这是我的结果。我用来测试的命令是
cl /nologo /W0 /we4715 <path to file>
| Test |
C |
C++ |
| Test 1 |
No warning or error |
Triggers C4716 as an error, even though this is not turned on (which makes sense, as the docs for this warning say it is automatically promoted to error unless #pragma warning is used to prevent this) |
| Test 2 |
No warning or error |
Triggers C2561 (a compiler error) |
| Test 3 |
Triggers C4715 |
Triggers C4715 |
这意味着 C4715 对于 C++ 来说已经足够了,但对于 C 来说还不够。
笔记
如果您调用一个永不返回的函数,C4715 可能会发出警告。例如,如果调用函数体为while (true) {} 或throw "error message"; 的函数。为避免这种情况,请使用 __declspec(noreturn) 声明永远不会返回的函数,或者如果您使用 C++11 或更高版本,则可以在函数声明中使用更便携的 [[noreturn]]。 (如果您正在调用像exit() 这样的标准库函数,编译器不会发出警告,因为它会知道该函数永远不会返回。)
有关一些有趣的相关讨论,请参阅Why does flowing off the end of a non-void function without returning a value not produce a compiler error?。