【问题标题】:Is there a tool to test the conciseness of c program? [closed]有没有工具可以测试c程序的简洁性? [关闭]
【发布时间】:2011-11-07 17:43:47
【问题描述】:

例如我想检查下面的代码是否可以更简洁:

for(i = 0; i < map->size; i++){
    if(0 < map->bucket[i].n){
        p = map->bucket[i].list;
        while(p){
            h = hash(p->key) % n;
            if(bucket[h].list){
                new_p = bucket[h].list;
                while(new_p->next)new_p = new_p->next;
                new_p->next = p;
                next = p->next;
                p->next = NULL;
                p = p->next;
            }
            else{
                bucket[h].list = p;
                bucket[h].n++;
                next = p->next;
                p->next = NULL;
                p = p->next;
            }   
        }
    }
}

这种任务有什么工具吗?

这对我很有帮助。

【问题讨论】:

标签: c static-analysis micro-optimization


【解决方案1】:

您可以尝试使用优化编译它并查看优化的汇编代码。但是,由于编译器无论如何都优化了所有额外的东西,因此您在速度方面确实没有获得任何收益。您所获得的只是提高了可读性。

【讨论】:

    【解决方案2】:

    您可能会在这里要求几件事情。对您的问题的一种可能解释是,您正在寻找一个切片器,这是一种工具,它采用程序并生成由原始程序中的指令选择组成的程序,并计算部分或全部原来的结果。换句话说,切片器会删除至少对您感兴趣的结果之一不必要的指令。

    有一个用于 C 程序的开源切片器 here

    为了使程序更简洁,可能只保留原始程序中的指令的限制太强了。您可能还希望允许“保留”或“删除”以外的一些转换。上面链接的切片器是其中一部分的框架也提供了这种转换。例如:

    int main(int c, char **v)
    {
      int x = 2;
      int y = x + c;
      return y; 
    }
    

    在上面的程序中,被指示保留退出代码的切片器不能删除任何指令:它们都对结果有贡献。但是,如果您首先应用常量传播,将每个常量表达式转换为其值:

    int main(int c, char **v)
    {
      int x = 2;
      int y = 2 + c;
      return y; 
    }
    

    然后切片器可以在第二遍中删除无用的变量x

    int main(int c, char **v)
    {
      int y = 2 + c;
      return y; 
    }
    

    【讨论】:

    • +1,很高兴知道这样的工具~
    【解决方案3】:

    答案是合格的“否”,

    • 不,因为不可能编写一个总是回答代码是否可以更简洁的程序。如果这样的程序可以存在,您可以使用它来创建一个逻辑悖论(这就是我们知道它不存在的原因)。

    • 这种性质的程序通常不存在,因为以机械方式缩小源代码会降低代码的可读性。大多数程序员只是没有看到使 C 代码尽可能小有任何好处。

    • 可以,因为可以使用静态分析来查找死代码。

    人们对使用静态分析自动使程序更小和更快进行了大量研究,但几乎所有这些研究都用于为编译器制作更好的优化器。优化器可以产生几乎不可读的输出,这就是为什么我们不使用它们来生成源代码而只使用目标代码。

    保持源代码整洁易读。编译器会在 99% 的时间里处理剩下的事情。

    【讨论】:

    • 逻辑上更简洁只会让代码在 IMO 上更具可读性。
    • @Je Rog: #!/usr/local/bin/perl -s do 'bigint.pl';($_,$n)=@ARGV;s/^.(..) *$/0$&/;($k=unpack('B*',pack('H*',$_)))=~ s/^0*//;$x=0;$z=$ n=~s/./$x=&badd(&bmul($x,16),hex$&)/ge;while(read(STDIN,$_,$w =((2*$d-1+$z )&~1)/2)){$r=1;$_=substr($_."\0"x$w,$c=0,$w);s/.|\n/$c= &badd(&bmul($c,256),ord$&)/ge;$_=$k;s/./$r=&bmod(&bmul($r,$r),$x),$&?$r =&bmod(&bmul($r,$c),$x):0,""/ge;($r,$t)=&bdiv($r,256),$_=pack(C,$t)。 $_ while$w--+1-2*$d;print}
    • 请首先以良好的格式发布。我的问题不是格式,也不是漂亮的代码,而是逻辑简洁性,所有 c 程序员都应该非常关心。
    • @Dietrich:真的不可能编写一个总是回答代码是否可以更简洁的程序吗?在我看来应该是这样,但我现在没有看到(对角化)证明。
    • @DaveBall:你可以使用这样的程序来解决停机问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多