我正在尝试使用Splint检查C程序(在严格模式下)。我用语义注释注释了源代码,以帮助Splint 理解我的程序。一切都很好,但我无法摆脱警告:
语句无效(可通过调用无约束函数my_function_pointer进行未定义的修改)。
声明没有明显效果---没有修改任何值。它可以通过调用无约束函数来修改某些东西。 (使用-noeffectuncon来禁止警告)
这是由函数指针调用函数引起的。我不想使用no-effect-uncon
标志,而是写一些注释来修复它。所以我用适当的typedef
子句装饰我的@modifies
,但是Splint似乎完全无视它。问题可以简化为:
#include <stdio.h>
static void foo(int foobar)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
{
printf("foo: %d\n", foobar);
}
typedef void (*my_function_pointer_type)(int)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/;
int main(/*@unused@*/ int argc, /*@unused@*/ char * argv[])
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
{
my_function_pointer_type my_function_pointer = foo;
int foobar = 123;
printf("main: %d\n", foobar);
/* No warning */
/* foo(foobar); */
/* Warning: Statement has no effect */
my_function_pointer(foobar);
return(EXIT_SUCCESS);
}
我已经阅读了manual,但是关于函数指针及其语义注释的信息并不多,所以我不知道我做错了什么或者这是某种错误(由方式,它尚未列在此处:http://www.splint.org/bugs.html)。
有没有人设法在严格模式下使用Splint成功检查这样的程序?请帮我找到让Splint高兴的方法:)
提前致谢。
更新#1: splint-3.1.2(Windows版本)产生警告,而splint-3.1.1(Linux x86版本)不会抱怨它。
更新#2: Splint不关心作业和通话是短还是长:
/* assignment (short way) */
my_function_pointer_type my_function_pointer = foo;
/* assignment (long way) */
my_function_pointer_type my_function_pointer = &foo;
...
/* call (short way) */
my_function_pointer(foobar);
/* call (long way) */
(*my_function_pointer)(foobar);
更新#3:我对禁止警告不感兴趣。这很简单:
/*@-noeffectuncon@*/
my_function_pointer(foobar);
/*@=noeffectuncon@*/
我正在寻找的是正确的方式来表达:
“此函数指针指向
@modifies
个函数的函数,因此 具有副作用”
答案 0 :(得分:1)
在你的my_function_pointer
作业中依靠从“函数名称”到“指向函数的指针”的隐式转换,你可能会混淆splint。相反,请尝试以下方法:
// notice the &-character in front of foo
my_function_pointer_type my_function_pointer = &foo;
现在你有一个明确的转换,并且splint不需要猜测。
但这只是猜测。我还没有测试过。
答案 1 :(得分:0)
我不熟悉splint,但它在我看来它将检查函数调用以查看它们是否产生效果,但它不会进行分析以查看函数指针指向的内容。因此,就它而言,函数指针可以是任何东西,“任何东西”包括没有效果的函数,因此你将继续获得任何使用函数指针调用函数的警告,除非你这样做具有返回值的东西。手册中功能指针不多的事实可能意味着它们无法正确处理它们。
对于整个语句,是否存在某种“信任我”注释,您可以通过指针使用函数调用?它不太理想,但它可以让你干净利落。
答案 2 :(得分:-1)
我相信警告是正确的。你将一个值作为一个指针但是什么也没用。
演员表只是以不同的方式显示价值;它不会以任何方式改变价值。在这种情况下,您已经告诉编译器将“foobar”视为指针,但由于您没有对该视图执行任何操作,因此该语句没有执行任何操作(无效)。