當前位置: 華文星空 > 知識

你用過的最好的程式碼閱讀或編輯工具是什麽?

2011-03-07知識

閱讀優秀計畫的原始碼是程式設計師自我提高的重要途經,因此好的工具能夠幫助你事半功倍。就像 Lua 這樣的開源計畫,官方文件可能你花一天就看完了,但是原始碼很多人一個月都看不明白,而 好的工具可以幫助你加速這個過程。

最早我直接用 VS 讀程式碼,後來用 source insight 代替了 vs,再後來用的 vim + ctags/gtags ,其他亂七八糟的東西也都試用過,最近幾年我只用 understand。

我是建議所有使用 source insight 的使用者遷移 understand,因為 si 這貨基本十多年沒更新了(雖然最近出了個 4.0),而 si 有的功能 understand 基本全覆蓋:

簡單使用下的話,點選 「地球圖示」進入瀏覽模式,然後滑鼠直接點選程式碼區的符號(函式、變量名),下面預覽視窗(Previewer)就會顯示符號的相關程式碼,雙擊 Previewer 又可以在上面程式碼區開啟對應程式碼。

同時左下角有符號詳情面板,詳細列舉了符號的定義,參照,被呼叫,以及呼叫的東西,這些資訊 si 也有,但是沒有這麽方便。

初次使用需要在下拉選單 View 中,顯示:Previewer, Project Browser 還有 Scope List 三項:

View 選單,允許顯示:Previewer, Project Browser 和 Scope List

其中 Previewer 就是前面螢幕擷取中最下面的符號預覽視窗,Project Browser 是左邊的計畫檔列表,Scope List 是右邊的符號列表,這樣 si 基本全覆蓋了。

Understand 同時支持:C/C++, Python, Java, 組譯,VB,C#,Fortran,Ada,VHDL,Delphi/Pascal 等等十多種語言,比 si 豐富不少。

對比 Vim + gtags/ctags/cscope/grep:

最主要的就是 understand 真的是在分析原始碼,是在理解原始碼,而 gtags/ctags 之類的只是在按格式掃描文字檔案,我舉個例子,宏的條件編譯,gtags/ctags 就無法辨識:

Understand 能夠正確分析程式碼,並對宏運算式進行求值,準確辨識有效程式碼

一般而言符號定義只有一處,而有時候用 vim+ctags/gtags 搜尋符號定義,經常會搜尋出 7,8 個定義出來,因為 ctags/gtags 只會匹配字串:

第一:ctags/gtags 無法處理宏,比如多個平台下都實作了同一個函式,並且用宏來進行條件編譯,ctags/ gtags 就傻了,會搜尋出很多無關結果來。

第二:對於同名但是參數不同的符號,understand 能夠根據呼叫時候的參數型別,精準的匹配到對應的定義,而 ctags 這種時候基本也就掛了,只能給你全部列出來。

第三:ctags/gtags 資料庫中的函式,比如 class1::update(),雖然它也會記錄 class1,但是實際在 Vim 使用的時候,比如 x->update() 這樣的語句,任何 ctags/gtags 的 vim 外掛程式都沒法分析出 x 是個什麽型別,因此這樣搜尋定義的時候,ctags/gtags 會搜尋出所有叫做 update 的函式。

上面三點導致用 vim+ctags/gtags/grep 經常無法準確的給我找出定義來,C 語言還稍微好一點,沒有第二和第三個問題,C++ 的話,ctags/gtags 基本沒法看。

很可惜,最新的 Source Insight 4.0 也無法理解程式碼裏面的宏:

而 Understand 可以準確辨識出有效的程式碼塊:

有些人可能會說,si 難說辨識出來了,只是沒有標紅顯示,那麽換張圖,隨便加兩行程式碼:

Source Insight 4.0 中無法分辨宏,尋找 TEST_1 定義會得到多個結果,si 4.0 無法辨識哪個有效

上面這個對比只是冰山一角,原因就是 vim+ctags/gtags/grep 是基於字串分析的,si 也沒有好到哪裏去,而 understand 是真的是基於語意的分析,他們我都用過好多年,差距是非常明顯的。

預覽視窗

這個功能類似 si,就是上面程式碼視窗點選了任意符號,最下面預覽視窗就立馬出現相關程式碼:

用這個預覽視窗閱讀程式碼效率是非常高的,通常瞥一眼符號定義的話,用它就夠了,想詳細看,雙擊預覽視窗,就會在上面程式碼區開啟原始碼,vim 也有外掛程式弄出這樣一個預覽視窗來,並且 vim 本身也有預覽窗,甚至懸浮預覽窗,然而由於 ctags/gtags/grep 沒法準確求解定義,經常會給出 7-8 處結果來,弄得你預覽非常低效,經常要切換過來切換過去。

Understand 是圍繞程式碼閱讀來設計的,所有 UI/UE,快捷鍵,滑鼠操作方法,都是為了讓讀程式碼更方便而生的。過去用 Visual Studio 開發時,它也可以跳到定義處,但是這個跳轉操作,實際體驗比預覽低效很多,大部份時候其實你只需要預覽一下。

符號詳情

就是第一張圖左下角的那個資訊視窗,瀏覽模式下點選任意符號就出現:

可以讀讀符號視窗裏的資訊有多詳細,這個視窗已經足夠秒殺任何 si 和 vim+ctags/gtags/grep 或者 Visual Studio 了,不但資訊豐富程度秒殺他們,而且用起來真的方便,符號視窗上面那些藍色的字型,滑鼠單擊就可以在下方的預覽視窗預覽,不需要開啟新檔,或者切換檔。

對比 Visual Studio

雖然 vs 也有尋找定義,尋找參照,但大家發現沒有,很多用 vs 的使用者過去都會用 si 來閱讀程式碼,舉個簡單例子,si 優勢之一,程式碼視窗和預覽視窗搭配十分方便,有時候一個原始碼開啟,我可能要對十多處符號檢視定義,有預覽視窗的話,滑鼠點點點看下邊就行了,vs 會給你開啟一堆檔,把你原來的工作區都擠沒了,或者有個 「Peek Definition" 的功能,會在你當前原始碼那裏插入一段目的碼,看完了還要你手工去關閉。

而 Understand 的:原始碼視窗+預覽視窗+符號資訊視窗,三合一互相搭配的工作流,可以比 vs 和 si 都方便。同時還是那句老話,閱讀程式碼不是簡單搜尋個定義和參照,而是 UI/UE + 數據,一體化解決方案,專業程式碼閱讀軟體,是圍繞讀程式碼設計的,最方便的快捷鍵,最好的 UI 位置,都給了 「讀程式碼」 這件事情,還有各種特有的功能面板,啟是普通 IDE 符號搜尋功能可以代替。

過去用 vs 很多年的人,都會選擇 si 讀程式碼,而今天他們有了比 si 更好的選擇。

對比 Sourcetrail

這貨我試用過,真的很弱智,和 understand 比較起來就像三歲小孩比成年人的感覺,sourcetrail 也就是最近兩年才出來的東西,是開源作者個人興趣計畫,而 understand 是商業團隊持續叠代了 15 年以上的產品,能比麽?

豐富的圖表

因為 si 持續十多年不更新,而 understand 相當於一個繼續叠代了十多年的 si,因此 si 有的圖表,understand 只多不少,比如符號的 butterfly 圖:

左邊是 Slerp 這個函式的呼叫者,右邊是它呼叫的東西,二者結合能讓你對該符號在計畫中的位置有一個值觀了解。這個圖 gtags 都沒法生成,因為 gtags 雖然可以找到 callers,卻無法找出 callees。

比如計畫鳥瞰圖:

這個計畫鳥瞰圖基本秒殺 si 和 vim+ctags/gtags 了,每個方塊都可以點選,檢視細節。

還有各種全域統計:

流程圖:

以及其他:定義圖,繼承圖,UML圖,依賴圖,Tree Map ,交叉參照圖:

等等,應有盡有。還有很多其他功能,不一一例舉了。。。

總的來講,作為 source insight, vim+ctags/gtags/grep, understand 每樣都用了三年以上的人來講,用 understand 閱讀程式碼是效率最高的,最方便的方式,基本能將你效率提升一倍以上。特別是閱讀一些陌生的,復雜的原始碼,understand 能夠幫你更快速的理清楚各個模組的內在聯系。

如果一個工具能夠在未來數年內都讓你受益,那麽完全值得花一天時間試用評估一下,understand 同時支持 windows, linux, macos 三大平台,基本不會有任何門檻。

--

補充:Understand 是如何解析宏的,第一是 Understand 可以直接匯入 Visual Studio 的 sln 檔,以及 CMake 的 cache 數據,裏面都有一些基礎的宏的定義,Understand 可以用這些基礎宏對更高級的宏運算式求值。

另外一個是,對於一些沒有工程檔,純粹程式碼的裸計畫而言,Understand 可以手動設定宏:

它支持預定義,匯入匯出,右下角的 "Undefined Macros" 按鈕還能告訴你哪些宏沒有定義,並不需要你定義所有宏,一般定義幾個和平台相關的基礎宏就夠了,其他 Understand 能夠根據他們進行宏運算式求值。

當然有條件的話,還是建議直接匯入工程計畫,這樣更省事,也更準確些。

--

在我解除安裝 Source Insight 4.0 之前,最後在對比一次:

在搜尋 obj->update 這個方法的時候,si 可以辨識到 obj 的型別是 Bar,這很好,但是沒法做參數匹配,找到正確的 update 函式原型,而 understand 卻沒問題:

可以看到 understand 找到了正確的函式原型。再來對比下 vim+ctags:

光標停在 21 行 obj->update(5) 的 update 處,g],好樣的,vim 果然不負眾望,幫我找到了 5 個 update 定義,根本不知道正確的是誰。

誰是誰非,高下立判。

--

收藏比點贊高 50%,什麽情況?點個贊有心理陰影麽?

--