当使用Microsoft的/analyze
静态分析命令行选项对cl.exe
进行编译时,我收到警告
warning C6011: Dereferencing NULL pointer 'foo'
在代码路径上调用一个平凡的函数,该函数保证foo
在分析器认为可以为NULL的地方不为NULL。
平凡函数:
bool check_ptr(void* ptr)
{
if (!ptr)
{
// The original does more things here, but
// the repro is valid even without that.
return false;
}
return true;
}
调用站点:
foo_t* foo = lookup_foo(id);
if (!check_ptr(foo))
return;
foo->bar = 4711; // warning C6011: Dereferencing NULL pointer 'foo'
分析器在看穿函数调用方面确实很糟糕,即使是微不足道的调用。
bool check_ptr(void* ptr)
{
return !!ptr;
}
那么分析器可以推断出foo
在解引用时不能为NULL,但这不是一个选项。
因此,我假设有一个不可靠的SAL注解组合可以应用于check_ptr
,以使分析器确信如果它返回true
,则foo
参数不是NULL。
是否有此类SAL注解?
**编辑:**我找到了SAL解决方案,并将其作为单独的答案添加https://stackoverflow.com/a/74459650/6345
2条答案
按热度按时间mkshixfv1#
我找到了一种方法,可以使用
_Post_equal_to_
对check_ptr
函数进行SAL注解,以便分析器知道它的作用。通过使用_Post_equal_to_(!!p)
对函数返回声明进行注解,分析器知道如果p
为非NULL,则返回值为非零。在godbolt / Compiler Explorer上添加了一个完整的最小复制示例,看起来更像我代码中的实际使用场景。注意
UNCOMMENT NEXT LINE TO REMOVE
注解。ijnw1ujt2#
这并不完全是使用SAL,而是一个应该始终有效的通用答案:您可以使用两个lambda来代替返回bool:一个用于then,一个用于else:
您甚至可以在一个呼叫中同时使用
lookup_foo()
和if_check_ptr()
。