2014年4月23日

[程式] 程式設計師永遠都會遇到的難題:document

注意:這是一篇抱怨 document 的問題多到讓我抓狂抱怨文

學過程式一段時間而且有看過 coding style 或是 clean code 之類的書籍或文章的應該都知道要有良好的註解或是 document,不然就是 coding 要注意命名、寫法之類的以提升程式可讀性,不過工程師最常做的就是懶得寫註解或文件。這到底有多重要呢?重要到看到兩個都做很差的程式會讓人腦溢血阿!!


其實事情是這樣的, 最近因為要參加比賽,題目的測資用的是 LEF/DEF 這兩種檔案格式。LEF/DEF 分別是這兩個的簡稱:

Library Exchange Format (LEF) 



Design Exchange Format (DEF)

我相信看完名字就知道這是啥東西的人就只有接觸過的人XD 不過簡單來說這兩種檔案格式定義了 IC  的一些參數以及長相,不過因為這些資訊相當的龐大複雜,所以這兩種檔案格式也是複雜到會讓人抓狂...舉例來說,就像面試臺灣公司填履歷時不知為何要你把祖宗十八代在幹啥都寫進去一樣非常莫名其妙,要十分詳盡的描述你這個人(雖然我覺得相親搞不好都不需要說得這麼詳細),這兩種檔案格式也會詳實的描述這顆 IC 的一些必要資訊。不過大會很貼心的把 parser 也附上了 (不過那下載程序實在有夠囉嗦),所以 parser 的部分就不用自己寫了,只要搞懂這個 parser 怎麼使用即可。不過這慘案就是這個 parser 帶來的...

這 parser 確實讓我大開眼界,我是第一次見到僅僅只是要讀一個檔案的 "範例" 就有將近 3000 行程式碼。打開範例一看更加吐血:稀稀疏疏的註解、充滿不知所云的魔法數字 (註1)、沒有任何的文件可以參考,API 的說明簡略到讓人抓狂。比方說這個:

defrRead
Specifies the DEF file to read. Any callbacks that have been set are called from within this
routine. If the file parses with no errors, that is, all callbacks return OK condition codes, this
routine returns zero.
Syntax
int defrRead(
FILE* file,
const char* fileName,
defiUserData* data,
int case_sensitive)
Arguments
file              Specifies a pointer to an already open file. This allows the parser to work with either a disk file or a piped stream. This argument is required. Any callbacks that have been set will be called from within this routine.

fileName    Specifies a UNIX filename using either a complete or a relative path specification.

data           Specifies the data type.

case_sensitive    Specifies whether the data is case sensitive.

看起來好像很正常?defrReaf 這個 function 需要 4 個參數、由回傳值可以得知有沒有遇到問題 (註2),function 本身會做什麼事情也有描述。問題就出在參數那邊的說明:

"data           Specifies the data type."  --> 所以是要怎樣描述資料型態阿?
"case_sensitive    Specifies whether the data is case sensitive." -->我要怎麼用一個整數來說明我要不要區分大小寫阿?

看到範例依舊無法幫我解答這兩個問題,因為範例上是這樣寫的

defrRead(f, inFile[fileCt], (void*)userData, 1);

其中 userData 是這個:

int userData;
userData = 0x01020304;

誰來告訴我為什麼型態會從 int -> void* -> defiUserData* 而且他的值還是 0x01020304 這個完全不知所云的數字阿....沒有註解、沒有說明。

case_sensitive 這參數也挺絕的:就給了一個 1 然後沒有任何說明,所以 1 到底是要區分大小寫還是不用阿?

諸如此類的問題遍佈整個說明檔,然後就被搞到快吐血了...所以說明檔跟註解是非常重要的東西,不然會發生命案的不過論我下次程式寫一寫還是懶得寫註解跟文件的可能性...



註1:Magic Number 是指那些出現在程式碼中不知用途為何的數字。在 C/C++ 中常見的忠告是利用 define、const 或是 enum 之類的手法將這些數字取個名稱,如此可增加程式的可讀性,免去猜測該數字的意義為何。

註2:常見的 error code 的做法。藉由回傳值來判斷 function 值型的過程中有沒有遇到問題或是遇到什麼樣的問題,在沒有 exception handling 的程式語言是常見的手法。即便語言本身有提供例外處理機制,這兩者之間也是有許許多多的紛爭,各自有各字的擁護者,可以參考這一篇文章


沒有留言:

張貼留言