2012-09-25 52 views
1

編譯器在函數範圍內檢測未使用的變量。但是,我發現在結構中定義了許多變量,這些變量從不讀取(但可能已經寫了很多次)。是否有任何工具/分析器或甚至編譯器標誌來檢測這些未使用的變量?檢測函數範圍之外的未使用變量

示例: 例如,在以下結構:

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

分析器可能會發現count永遠不會在代碼的任何地方讀取。

我對我的代碼的分析顯示這經常發生!這是我的錯,但這可能是多年來由不同用戶開發的應用程序的常見情況。刪除這些變量可能會顯着減少內存使用量。我只需要一個工具來檢測這些變量,我會手動刪除它們。

在此先感謝。

+4

[這裏是一個列表](http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#C.2FC.2B.2B)用於C和C++的靜態分析工具。他們中的一些人可能能夠檢測到你的情況。 –

+0

哦,我有很多這些。不能被打擾修復它們。與DID需要修復的其他大規模開發工作相比,除非嵌入式代碼具有有限的內存(這種情況下,我將消除所有未使用的內存位),否則這對於我來說是一個微不足道的問題。 –

回答

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()後打印。您可以將這些數據收集到一些外部文件。

+0

好包裝!我有一個鏈接列表數據結構,我使用malloc()分配一個節點,釋放()釋放它。我認爲這就是爲什麼這個包裝沒有檢測到未使用的變量(注意:我手動找到了未使用的變量)。使用malloc/free時,我看起來不會調用解構器!我對嗎? – ahmad

+0

靜態元素的d-tor應該被調用 - 就像你在我的例子中可以看到的那樣:即使我將'A a;'改變爲'A * a = new A;',它也可以工作。沒有看到這個打印輸出的原因可能是不同的 - 也許在'main()'之後,所有打印輸出都被丟棄。無論如何 - 這不是真正的解決方案 - 只是一個想法,表明跟蹤所有變量的讀數是可能的。 – PiotrNycz

1

任何分析都必須跨越翻譯單位。

實際上,與您不同,我從未發現這是一個問題。關於 我能想到的唯一解決方案就是刪除 之一的成員,並查看整個應用程序是否仍在編譯。

+0

使用__attribute __((不建議使用))會比刪除少一點激進;-) – stefan

+1

OP:「(但可能已經寫了很多次)」? – PiotrNycz

+0

如果變量沒有讀取不寫,請確定。但是,沒有閱讀很多寫道呢!! – ahmad

-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. 

所以,很難做到你要求的分析。

+1

-1。所提供的代碼是不可編譯的,因爲除了這個相同類型的另一個結構之外,你不能分配給一個結構,但是你想給它賦一個整數(5)。此外,這不能回答這個問題。這可以很好的評論。 –