2009-02-18 81 views
8

我想從C文件中刪除未使用的局部變量。 例如:自動從C源代碼中刪除未使用的局部變量

int fun(int a , int b) 
{ 
    int c,sum=0; 
    sum=a + b; 
    return sum; 
} 

這裏未使用的變量是'c'。

我將在外部列出所有未使用的局部變量。現在使用我沒有使用的局部變量,我們必須從源代碼&刪除中找到局部變量。
在上面例子中「c」是未使用的變量。我會知道它(我有代碼)。 這裏我要找到c &刪除它。

編輯

的關鍵不在於找到一個外部工具未使用的局部變量。重點是從給定列表中刪除它們。

+0

當然,你可以進一步,並說「int fun(int a,int b){return a + b;}」,並且消除sum。但那不是你的問題。 – 2009-02-18 12:51:15

+0

你有沒有使用的變量列表的格式是什麼?它是否有行號和列號? – Constantin 2009-02-18 13:30:01

+0

你爲什麼要這麼做?什麼阻止你手動刪除未使用的變量,只要它們變爲未使用?或者你的同事是否有意將它們放入代碼中,並告訴你在列表中刪除它們? – 2009-02-22 00:58:53

回答

20

調高你的編譯器警告級別,它應該告訴你。

請辭 「F.C」 源片段:

% gcc -c -Wall f.c 
f.c: In function 'fun': 
f.c:1: warning: unused variable 'c' 
-1

另外:splint

Splint是一個工具,用於靜態檢查C程序的安全漏洞和編碼錯誤。以最小的努力,Splint可以被用作更好的皮棉。如果爲程序添加註釋額外的努力,Splint可以執行比任何標準lint都可以做的更強的檢查。

1

除了能夠通過警告揭示這些,編譯器通常會優化這些,如果任何優化開啓。就編譯器的實現而言,檢查一個變量是否從未被引用是相當微不足道的。

10

整蠱 - 你將不得不解析C代碼。結果有多接近?我的意思 例子:

int a, /* foo */ 
    b, /* << the unused one */ 
    c; /* bar */ 

現在,這是明顯的是,第二個評論已去人類。

輕微變化:

void test(/* in */ int a, /* unused */ int b, /* out */ int* c); 

同樣,第二個評論已去,一個b之前這段時間。

一般來說,你想分析你的輸入,過濾它,併發出一切不是未使用變量的聲明。你的解析器必須保留註釋和#include語句,但是如果你不包含#include頭文件,可能無法識別聲明(如果使用宏來隱藏聲明,則更是如此)。畢竟,你需要標題來決定是否A * B();是一個函數聲明(當A是一類)或乘(當A是一個變量)


[編輯]此外:

即使你知道一個變量是未使用的,有道刪除它取決於遠程上下文。例如,假設

int foo(int a, int b, int c) { return a + b; } 

顯然,c未被使用。你能改變它嗎?

int foo(int a, int b) { return a + b; } 

也許吧,但如果& foo的存儲INT一個int(*)(int,int,int)。而這可能發生在別的地方。如果(且只有)發生這種情況,您應該將其更改爲

int foo(int a, int b, int /*unused*/) { return a + b; } 
5

爲什麼要這麼做?假設你有一個體面的優化編譯器(GCC,Visual Studio等),二進制輸出與你在原始示例中刪除'int c'沒有任何區別。

如果這只是代碼清理,所有最新的IDE會給你快速鏈接到每個警告的源代碼,只需點擊刪除:)

5

我的回答是更MSalters'一個精心製作的評論非常徹底的答案。 我會超越'棘手',並說這樣一個工具是不可能的和不可取的。

如果您正在尋找簡單地刪除該變量的引用,那麼你可以編寫自己的代碼分析器,但它需要它在功能方面進行區分,如

int foo(double a, double b) 
{ 
    b = 10.0; 
    return (int) b; 
} 

int bar(double a, double b) 
{ 
    a = 5.00; 
    return (int) a; 
} 

任何簡單的解析器都會遇到麻煩,'a'和'b'都是未使用的變量。其次,如果你考慮MSalter的評論,你會發現人們並不一致評論;

double a; 
/*a is designed as a dummy variable*/ 
double b; 

/*a is designed as a dummy variable*/ 
double a; 
double b; 

double a; /*a is designed as a dummy variable*/ 
double b; 

所以簡單地刪除未使用的變量會創建孤立的意見,這可以說是比not commenting at all更危險。

最終,優雅地做這件事是一件難以處理的艱鉅任務,無論如何你都會損壞代碼。通過自動化流程,您可能會使代碼變得更糟。

最後,您應該首先考慮變量在代碼中的原因,並且如果它們已被棄用,那麼爲什麼在所有引用都不刪除時它們不會被刪除。

0

您將需要一個很好的解析器來保存原始的字符位置(即使在預處理器中!)。有一些自動重構C/C++的工具,但它們遠非主流。

我推薦你去看看Taras' Blog。這個人正在做一些Mozilla代碼庫的大型自動重構,比如用返回值替換out-params。他的代碼重寫主要工具是Pork

豬肉是一個C++解析和重寫 工具鏈。 Pork的核心是C++ 解析器,它爲每個AST節點的起始和末尾提供精確字符 位置,以及包含任何 位置的一組 宏擴展。此信息允許C++ 以精確的方式自動重寫爲 。

從博客:

到目前爲止,豬肉已被用於「小」 之類的東西重命名 類&功能,旋轉 outparameters和糾正prbool 錯誤。此外,豬肉在一個實驗中證明了自己 ,其中涉及 在Mozilla中將幾乎所有功能(即生成3 + MB補丁的 )重寫爲 使用垃圾回收而不是 引用計數。

它適用於C++,但它可能適合您的需求。

0

上面的海報之一說「不可能和不可取」。 另一個說「棘手」,這是正確的答案。 您需要1)完整的C(或任何感興趣的語言)解析器, 2)理解語言 標識符引用和數據流的推理過程,以確定變量 確實「死亡」,以及3)實際上修改了 的源代碼。

所有這一切都很困難是建立的巨大能量 1)2)3)。你無法爲任何個人清理任務辯護。 我們可以做的是建立這樣的基礎設施,特別是 ,其目標是在大量不同的 程序分析和轉換任務中攤銷。

我公司提供這樣的工具:DMS軟件再造 工具包。請參閱 http://www.semdesigns.com/Products/DMS/DMSToolkit.html DMS具有多種語言的產品質量前端, 包括C,C++,Java和COBOL。

我們實際上建立了一個自動化的「發現無用聲明」 工具爲Java做兩件事情: 一)列出了所有這些(從而產生列表) B)使代碼與無用副本聲明 已刪除。 你選擇你想要保留的答案:-)

爲C做同樣的事情並不困難。我們已經有 有一個工具來識別這些死變量/函數。

一個情況下,我們沒有addess,是「無用的參數」 情況下,becasue刪除無用的參數,你必須 從其他模塊發現所有的電話, 驗證設置參數沒有按」 t有一個方面 的影響,並撕掉無用的論點。 我們實際上有整個軟件 系統的完整圖表,所以這也可能是 。

所以,它只是很棘手,甚至不是非常棘手的 ,如果你有正確的基礎設施。

-1

您可以將問題解決爲文本處理問題。必須有少量的正則表達式模式,它們是如何在源代碼中定義未使用的局部變量的。

使用未使用的變量名稱列表以及它們所在的行號,可以逐行處理C源代碼。在每一行你可以迭代變量名稱。在每個變量名稱上您可以逐個匹配模式。成功的匹配之後您知道定義的語法,因此您知道如何從中刪除未使用的變量。

例如,如果源代碼行是:「int a,unused,b;」並且編譯器在該行中報告「未使用」爲未使用的變量,而模式「/,unused,/」將匹配,您可以用單個「,」替換該子字符串。

相關問題