有没有工具来测试c程序的简洁性?

时间:2011-08-31 15:32:55

标签: c static-analysis micro-optimization

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

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;
            }   
        }
    }
}

是否有任何工具可用于此类任务?

这对我有很大的帮助。

3 个答案:

答案 0 :(得分:3)

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

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 :(得分:1)

答案是合格的“不”,

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

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

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

人们使用静态分析将大量研究工作变得更小,更快,但几乎所有这些研究都应用于为编译器制作更好的优化器。优化器可以产生几乎不可读的输出,这就是为什么我们不使用它们来生成源代码而仅使用目标代码。

保持源代码的清洁和可读性。编译器将在99%的时间内完成剩下的工作。

答案 2 :(得分:1)

您可以尝试使用优化进行编译并查看优化的汇编代码。但是你真的没有在速度方面获得任何东西,因为无论如何编译器都优化了所有额外的东西。所有你获得的是可读性的提高。