- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我使用Frama-C工具来生成这个程序(main.c)的依赖图。
#include<stdio.h>
int main()
{
int n,i,m,j;
while(scanf("%d",&n)!=EOF)
{
m=n;
for(i=n-1;i>=1;i--)
{
m=m*i;
while(m%10==0)
{
m=m/10;
}
m=m%10000;
}
m=m%10;
printf("%5d -> %d\n",n,m);
}
return 0;
}
命令是:
frama-c -pdg -dot-pdg main main.c
dot -Tpdf main.main.dot -o main.pdf
结果是 我的问题是为什么语句“m=m*i;”,“m=m%10000”没有映射到节点。结果似乎不对,因为代码中有三个循环。
最佳答案
C 程序的切片器只有在其定义的目标是保留已定义的执行,并且允许切片器更改未定义的执行。
否则,一旦无法确定 p
是一个有效指针,切片器将无法删除诸如 x = *p;
的语句到那一点,即使它知道它不需要 x
,只是因为如果删除该语句,那时候 p
为 NULL 的执行将被更改。
Frama-C 不处理复杂的库函数,例如 scanf()
。因此,它认为局部变量 n
没有被初始化就被使用了。
输入frama-c -val main.c
您应该会收到如下警告:
main.c:10:[kernel] warning: accessing uninitialized left-value:
assert \initialized(&n);
...
[value] Values for function main:
NON TERMINATING FUNCTION
assert
这个词的意思是Frama-C的选项-val
无法确定所有的执行都被定义,而“NON TERMINATING FUNCTION”则表示无法找到一个已定义的程序执行以继续。
未定义的未初始化变量的使用是 PDG 删除大多数语句的原因。 PDG 算法认为它可以删除它们,因为它们发生在它认为未定义的行为之后,即第一次访问变量 n
。
我稍微修改了您的程序,用更简单的语句替换了 scanf()
调用:
#define EOF (-1)
int unknown_int();
int scan_unknown_int(int *p)
{
*p = unknown_int();
return unknown_int();
}
int main()
{
int n,i,m,j;
while(scan_unknown_int(&n) != EOF)
{
m=n;
for(i=n-1;i>=1;i--)
{
m=m*i;
while(m%10==0)
{
m=m/10;
}
m=m%10000;
}
m=m%10;
printf("%5d -> %d\n",n,m);
}
return 0;
}
我得到了下面的 PDG。据我所知,它看起来很完整。如果您知道比 dot
更好的布局程序但接受 dot
格式,这是使用它们的好机会。
请注意,最外面的 while
的条件变成了 tmp != -1
。图的节点是程序内部规范化表示的语句。条件 tmp != -1
对语句 tmp = unknown_int();
的节点具有数据依赖性。你可以用frama-c -print main.c
显示内部表示,它会显示最外层循环条件已经被分解为:
while (1) {
int tmp;
tmp = scan_unknown_int(& n);
if (! (tmp != -1)) { break; }
除其他外,这有助于切片以仅删除复杂语句中可以删除的部分,而不必保留整个复杂语句。
关于c - 为什么 Frama-C 的这个使用 scanf() 的程序的依赖图看起来像这样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9860017/
#include #include #include using namespace std::chrono; int main(int arc, char* argv[]) { con
我是 opencv 的新手。当我将 sRGB png 提供给它时,我发现以下代码交换了红色和蓝色 channel 。我应该责怪哪个函数,imread 还是 fromarray? 最佳答案 是的,O
我正在使用以下代码,它缩小了每一行,并且由于某种原因整个用户界面也丢失了。我该如何解决?
它是关于以下设置的:Linux 机器、bash、adb、带有 Busybox 的嵌入式 Linux 目标系统。对于目标系统,以下适用: adb shell echo $SHELL /bin/sh ad
当我在 Android Studio 上创建一个空 fragment 时,它会生成以下代码: /** * A simple {@link Fragment} subclass. * Activit
我正在尝试从 Meteor 应用程序的服务器端发布用户的 Facebook 提要: result = Meteor.http.call 'POST', "https://graph.faceb
目前我有两个不同的查询,它们返回完全相同的结果,但是,更改从中过滤结果的参数会使它们以非常不同的方式运行。 搜索 cartography 时的结果 查询 #1: 22 行/~860 毫秒; SELEC
我已经创建了结构: typedef struct { short s; int i; struct Ss { short s; }; } S;
我想在 Java 中打印反斜杠 t。但每当我尝试时,它实际上都将它作为\t 运算符。双反斜杠不起作用。我该怎么做。 最佳答案 例如通过添加另一个反斜杠来转义反斜杠 System.out.println
我想弄清楚为什么 UIActivityViewController 发送一个稍微转换过的字符串来分享给邮件和微信。 这是我的代码: let activityViewController = UIAct
创建标准 SQLite 游标后,我将使用以下方法遍历条目: while (cursor.moveToNext()) { } 所有行都被正确处理。我读过的所有文档都表明您需要发出 moveToFirst
我正在尝试创建一个基本论坛,但在 SQL 中仅打印一行时遇到问题。这是我的 PHP: {$title}"; } } else { print "failed to reach post
我的新 div 元素 ( ) 似乎隐藏在图像后面。我键入的任何内容都显示在图像后面。我想在背景图片之后继续工作。 这是我的代码: DISPLAY
UPD。一行代码解决了问题:.lean() axplanation here 我在 Model.find(...blablabla : [ {"_id":"578763de6e8e0542195ef4
我在 Ubuntu 16.04 中安装了 Tomcat 8.0.45。我使用 let's encrypt 生成的证书启用了 HTTPS 连接器。它就像一个魅力。但是今天Tomcat无法启动HTTPS连
今天,我在一台全新安装了 Windows 7 Ultimate 64 位的新笔记本电脑上安装了 Visual Studio 2010 Professional。我非常习惯于 Visual Studio
根据 Oracle,我应该能够将 .intValue() 和 .compareTo() 之类的方法应用于 double ,但是当我编写 dbl.toString( ) 例如,在 NetBeans 中,
正在为应用程序开发一些拖放功能,虽然可以使用“重影图像”来完成很多事情,将毒品从一个地方转移到另一个地方,但它们看起来总是有点“褪色” - 因此得名鬼影。是否有可能使这些具有与原始颜色相同的深度?谢谢
我是这方面的新手,很抱歉犯了一些愚蠢的错误。快乐学习。每当我使用 URL : localhost:3000/posts/whatever 时,我都会收到无法获取错误。在你问之前,是的,那是在我将内容放
背景 这自然是合法的: let closure: (Int, Int) -> () = { print($0 + $1) } closure(1, 2) // 3 鉴于,自进化提案实现以来 SE-01
我是一名优秀的程序员,十分优秀!