唉,一些老代码的作者是真的讨厌,各种陋习,比如不看函数的返回值是成功还是失败,就是一顿调用;Switch语句里面写了case不写break等。
有的作者甚至直接关闭编译器所有警告信息,意图“编译期干净”,简直不可理喻。
我们来介绍一下C++17标准下的编译器提示与关键词用法。
专治不看函数的返回值
#include <iostream>
using namespace std;
bool check(int x)
{
return x<10;
}
// Driver Code
int main()
{
for(int i=0;i<3;i++)
check(i);
}
这个地方的check根本不看是否合理,就是一顿循环,非常差劲。但是,我们开启所有警告也不会发现这个问题,因为返回值报警还没被纳入警告之中。
在C++17之中,引入了关键词`nodiscard`,用于标记函数返回值没有被处理的情形。
#include <iostream>
using namespace std;
[[nodiscard]] bool check(int x)
{
return x<10;
}
// Driver Code
int main()
{
for(int i=0;i<3;i++)
check(i);
}
这个时候,再次编译,就开始收拾这种情形了:
$ g++ a.cc -W
a.cc: In function ‘int main()’:
a.cc:13:14: warning: ignoring return value of ‘bool check(int)’, declared with attribute nodiscard [-Wunused-result]
13 | check(i);
| ~~~~~^~~
a.cc:4:20: note: declared here
4 | [[nodiscard]] bool check(int x)
| ^~~~~
这个关键词有趣的地方就是提供服务的人要求所有调用服务的人必须处理这个服务的返回值,而不是调用服务的人自己决定处理不处理,这个也符合服务的设计原则。
专治写case不写break
这个警告信息倒不是C++17的专利啦,一般来说我们希望自己的代码严谨,肯定是要把所有的警告都打开的,比如下面的代码
#include <iostream>
using namespace std;
// Driver Code
int main()
{
int n = 1;
// Switch Cases
switch (n) {
case 1: {
cout << "work through one \n";
}
case 2: {
cout << "work through two \n";
}
case 3: {
cout << "work through three \n";
}
default: {
cout << "work through default \n";
}
}
return 0;
}
一堆不写break的,各种逻辑错误已经预订了。
如何开启所有的编译器警告: `g++ a.cc -W`
$ g++ a.cc -W
a.cc: In function ‘int main()’:
a.cc:12:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
12 | cout << "work through one \n";
| ^~~~~~~~~~~~~~~~~~~~~
a.cc:14:5: note: here
14 | case 2: {
| ^~~~
a.cc:15:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
15 | cout << "work through two \n";
| ^~~~~~~~~~~~~~~~~~~~~
a.cc:17:5: note: here
17 | case 3: {
| ^~~~
a.cc:18:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
18 | cout << "work through three \n";
| ^~~~~~~~~~~~~~~~~~~~~~~
a.cc:20:5: note: here
20 | default: {
| ^~~~~~~
那么,这里如果有的break不写是有意为之,就要费精力去挨个检查,比较头疼,C++17引入了关键词`fallthrogh`,表明这种break不写是有意为之,就会减少警告条数。
#include <iostream>
using namespace std;
// Driver Code
int main()
{
int n = 1;
// Switch Cases
switch (n) {
case 1: {
cout << "work through one \n";
[[fallthrough]];
}
case 2: {
cout << "work through two \n";
[[fallthrough]];
}
case 3: {
cout << "work through three \n";
}
default: {
cout << "work through default \n";
}
}
return 0;
}
此时,警告会减少
$ g++ a.cc -W
a.cc: In function ‘int main()’:
a.cc:20:17: warning: this statement may fall through [-Wimplicit-fallthrough=]
20 | cout << "work through three \n";
| ^~~~~~~~~~~~~~~~~~~~~~~
a.cc:22:5: note: here
22 | default: {
| ^~~~~~~