Dra*_*sha 53 c c++ gcc static-analysis
我想看看我的代码(C++)中忽略函数返回值的所有位置.我怎么能用gcc或静态代码分析工具呢?
代码示例错误:
int f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}
int main()
{
int i = 7;
f(i); ///// <<----- here I disregard the return value
return 1;
}
Run Code Online (Sandbox Code Playgroud)
请注意:
Eri*_*nen 54
你想要GCC的warn_unused_result属性:
#define WARN_UNUSED __attribute__((warn_unused_result))
int WARN_UNUSED f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}
int main()
{
int i = 7;
f(i); ///// <<----- here i disregard the return value
return 1;
}
Run Code Online (Sandbox Code Playgroud)
尝试编译此代码会产生:
$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result
Run Code Online (Sandbox Code Playgroud)
你可以在Linux内核中看到这个; 他们有一个__must_check做同样事情的宏; 看起来你需要GCC 3.4或更高版本才能工作.然后你会发现内核头文件中使用的宏:
unsigned long __must_check copy_to_user(void __user *to,
const void *from, unsigned long n);
Run Code Online (Sandbox Code Playgroud)
小智 10
据我所知,没有GCC选项可以发出此警告.但是,如果您对特定功能感兴趣,可以使用以下属性标记它们:
int fn() __attribute__((warn_unused_result));
Run Code Online (Sandbox Code Playgroud)
如果没有使用fn()的返回值,它会发出警告.警告:我自己从未使用过此功能.
Joe*_*oeG 10
您可以使用此方便的模板在运行时执行此操作.
您不返回错误代码(例如HRESULT),而是返回一个return_code <HRESULT>,如果超出范围而没有读取值,则返回该断言.它不是一个静态分析工具,但它仍然有用.
class return_value
{
public:
explicit return_value(T value)
:value(value), checked(false)
{
}
return_value(const return_value& other)
:value(other.value), checked(other.checked)
{
other.checked = true;
}
return_value& operator=(const return_value& other)
{
if( this != &other )
{
assert(checked);
value = other.value;
checked = other.checked;
other.checked = true;
}
}
~return_value(const return_value& other)
{
assert(checked);
}
T get_value()const {
checked = true;
return value;
}
private:
mutable bool checked;
T value;
};
Run Code Online (Sandbox Code Playgroud)
对于C++ 17,这个问题的答案发生了变化,因为我们现在有了[[nodiscard]]属性.涵盖在[dcl.attr.nodiscard]中:
属性标记nodiscard可以应用于函数声明中的declarator-id或类或枚举的声明.它应该在每个属性列表中最多出现一次,并且不存在attribute-argument-clause.
和
[例如:
Run Code Online (Sandbox Code Playgroud)struct [[nodiscard]] error_info { /* ... */ }; error_info enable_missile_safety_mode(); void launch_missiles(); void test_missiles() { enable_missile_safety_mode(); // warning encouraged launch_missiles(); } error_info &foo(); void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither // the (reference) return type nor the function is declared nodiscard- 结束例子]
所以修改你的例子(现场直播):
[[nodiscard]] int f(int z) {
return z + (z*2) + z/3 + z*z + 23;
}
int main()
{
int i = 7;
f(i); // now we obtain a diagnostic
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我们现在获得gcc和clang的诊断例如
warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
f(i); // now we obtain a diagnostic
^ ~
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11180 次 |
| 最近记录: |