1

编译器在函数范围内检测未使用的变量。但是,我发现有很多变量定义在一个结构中,它们永远不会被读取(但可能已经被写入了很多次)。是否有任何工具/分析器甚至编译器标志来检测这些未使用的变量?

示例:例如,在以下结构中:

typedef struct jj_t {
    int count;
    int *list;
} jj;

分析器可能会发现count从未在代码中的任何地方读取过。

我对代码的分析表明这种情况经常发生!这是我的错,但这可能是多年来不同用户开发的应用程序的常见情况。删除这些变量可能会显着减少内存使用量。我只需要一个工具来检测这些变量,我会手动删除它们。

提前致谢。

4

3 回答 3

1

任何分析都必须跨越翻译单元。

实际上,与您不同,我从未发现这是一个问题。关于我能想到的唯一解决方案是一个一个删除成员,看看整个应用程序是否仍然编译。

于 2012-09-25T15:54:28.587 回答
1

我可以给出一个解决方案。

但:

  1. 这种努力可能比手动检查要大得多。几乎所有适合程序员的优秀 IDE 都允许您查看对给定变量的所有引用。

  2. 这可能不适用于每种情况,您需要专门针对某些类型。

  3. 这将由单个程序运行收集。

这个想法是包装你的数据类型。通过这样的封装,您可以计算每个读取操作。看:

template <class T, class Parent, int NO=1>
class TReadDetector {
public:
   struct Data {
      bool touched;
      Data () : touched(false) {}  
      ~Data ()  {
        if (!touched) 
          std::cerr << typeid(*this).name() << ": not read!!!\n" << std::endl;
      }  
   };
   static Data  data;
   TReadDetector () {}
   TReadDetector (const T& t) : t(t) {}
   operator T () const {    data.touched = true; return t; }
   TReadDetector& operator = (const T& t) { this->t = t; }
private:
   T t;
};

template <class T, class Parent, int NO>
typename TReadDetector<T,Parent,NO>::Data  
                       TReadDetector<T,Parent,NO>::data;

和用法:

代替:

struct A {
  int a;
  int b;
};

做这个:

struct A {
  TReadDetector<int,A, 1> a;
  TReadDetector<int,A, 2> b;
};


int main() {
  A a;
  a.a = 7;
  a.b = 8;
  std::cout << a.a << std::endl;
  std::cout << TReadDetector<int,A, 1>::data.touched << std::endl;
  std::cout << TReadDetector<int,A, 2>::data.touched << std::endl;
  std::cout << "main() ended" << std::endl;
};

这将导致:

7
1
0
main() ended
N13TReadDetectorIi1ALi2EE4DataE: not read!!!

注意在 . 之后打印的最后一行main()。您可以将此数据收集到一些外部文件。

于 2012-09-25T17:12:22.543 回答
-1

如果我们使用这样的结构,在少数情况下从结构中移除字段可能会很危险,

typedef struct jj_t {     int count;     int *list; } jj; 

jj *ptr = malloc (...);

//....

*ptr = 5; // NAIVE (but I have seen usage like this).
          // Actually you are not modifying count, count was already deleted.

因此,很难进行您要求的分析。

于 2012-09-25T17:06:49.880 回答