为什么 Frama-C 在基本示例中警告 'accessing uninitialized left-value'?
Why is Frama-C warning about 'accessing uninitialized left-value' in basic example?
Frama-C 认为下面的代码是正确的(没有警告,没有错误):
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
printf("*p = %d\n",(int) (*p));
}
return(1);
}
但是,如果我通过拆分 if-then-else 来稍微更改代码:
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
}
if (p!=NULL) {
printf("*p = %d\n",(int) (*p));
}
return(1);
}
我收到消息:
test6.c:13:[value] warning: accessing uninitialized left-value. assert \initialized(p);
问题是,为什么 Frama-C 认为 p
可能会访问未初始化的左值?我错过了什么?
我使用以下命令调用 Frama-C:
frama-c-gui -val test.c
抽象解释器通过在两个控制流路径相遇时执行抽象 ("joins") 来限制其分析的复杂性。这就是您的第二个示例所发生的情况:在第一个 if
结束后,两个分支的抽象被合并。在由此产生的抽象中,p
和 *p
的初始化之间的关系丢失了。
在 Frama-C/Eva 中,可以 not 在多个控制流路径相遇时执行连接,而不是并行传播状态集。这些集合的最大基数由参数 -slevel
控制。这里 -slevel 2
足以证明你的第二个例子。
Frama-C 认为下面的代码是正确的(没有警告,没有错误):
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
printf("*p = %d\n",(int) (*p));
}
return(1);
}
但是,如果我通过拆分 if-then-else 来稍微更改代码:
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
}
if (p!=NULL) {
printf("*p = %d\n",(int) (*p));
}
return(1);
}
我收到消息:
test6.c:13:[value] warning: accessing uninitialized left-value. assert \initialized(p);
问题是,为什么 Frama-C 认为 p
可能会访问未初始化的左值?我错过了什么?
我使用以下命令调用 Frama-C:
frama-c-gui -val test.c
抽象解释器通过在两个控制流路径相遇时执行抽象 ("joins") 来限制其分析的复杂性。这就是您的第二个示例所发生的情况:在第一个 if
结束后,两个分支的抽象被合并。在由此产生的抽象中,p
和 *p
的初始化之间的关系丢失了。
在 Frama-C/Eva 中,可以 not 在多个控制流路径相遇时执行连接,而不是并行传播状态集。这些集合的最大基数由参数 -slevel
控制。这里 -slevel 2
足以证明你的第二个例子。