Chapter 5: Typedefs


         5: Typedefs


 


Please don't use things like "vps_t".


請不要使用像 " vps_ t" 這種東西


 


It's a _mistake_ to use typedef for structures and pointers. When you see a


它是一個 _錯誤_ typedef用於結構和指標。當你看見a


 


    vps_t a;


 


in the source, what does it mean?


在程式碼中它是什麼意思呢?


 


In contrast, if it says


相反的,如果它寫成


 


    struct virtual_container    *a;


 


you can actually tell what "a" is.


現在能立刻的告訴我,"a" 是甚麼了吧


 


Lots of people think that typedefs "help readability". Not so. They are useful only for:


許多人以為那typedef "幫助可讀性"。但並非如此。他們只有用在:


 


 (a) totally opaque objects (where the typedef is actively used to _hide_


     what the object is).


 (a) 完全不透明的物件 (於此typedef被主動用於 _隱藏_ 此物件為何)


 


     Example: "pte_t" etc. opaque objects that you can only access using


     the proper accessor functions.


     例:如 "pte_t" 這類不透明的物件,只能使用較適當的存取函式來存取。


 


     NOTE! Opaqueness and "accessor functions" are not good in themselves.


     The reason we have them for things like pte_t etc. is that there


     really is absolutely _zero_ portably accessible information there.


     注意!不透明性與 "存取函式" 它們本身並非好事。


     pte_t這類物件之所以會存在,是因為於此處實在完全 __


     可攜可存取的資訊。


 


 (b) Clear integer types, where the abstraction _helps_ avoid confusion


     whether it is "int" or "long".


 (b) 清楚易懂的整數資料型別,利用抽象的念去 _幫助_ "int" 或者


     "long" 避免混淆


 


     u8/u16/u32 are perfectly fine typedefs, although they fit into


     category (d) better than here.


     u8/u16/u32是非常好的typedef,雖然在 (d) 項裡面談到的


     typedef比較好


 


     NOTE! Again - there needs to be a _reason_ for this. If something is


     "unsigned long", then there's no reason to do


     注意! 再說一次 一定要有一個 _理由_ 對應,假如本來就是


     "unsigned long"那就沒有什麼理由這樣做


 


    typedef unsigned long   myflags_t;


 


     but if there is a clear reason for why it under certain circumstances


     might be an "unsigned int" and under other configurations might be


     "unsigned long", then by all means go ahead and use a typedef.


     但是假如有一個很明確的理由說明為什麼myflags_t在一定的情況下


     可能是 "unsigned int" 且在其他情況下有可能是 "unsigned long"


     如此當然可以繼續使用typedef


 


 (c) when you use sparse to literally create a _new_ type for type-checking.


 (c) 當你使用稀疏字面上創造一個 __ 的型別來做型別檢查


 


 (d) New types which are identical to standard C99 types, in certain


     exceptional circumstances.


 (d) 新的資料型別在某些特殊情況下裡與標準C99型別是相同的


 


     Although it would only take a short amount of time for the eyes and


     brain to become accustomed to the standard types like 'uint32_t',


     some people object to their use anyway.


     雖然將花費較短的時間讓眼睛和大腦習慣於那些標準資料型別像


     'uint32_t' 一樣,無論如何,有一些人反對使用它們。


 


     Therefore, the Linux-specific 'u8/u16/u32/u64' types and their


     signed equivalents which are identical to standard types are


     permitted -- although they are not mandatory in new code of your


     own.


     因此,Linux制訂一組與標準型態完全相同的 'u8/u16/u32/u64'


     型態是可以容許使用在原始碼,雖然他們並沒有要求你的程式碼


     需要一致。


 


     When editing existing code which already uses one or the other set


     of types, you should conform to the existing choices in that code.


     當你在編輯一份已經有使用過其他型態設定的程式碼時,應該要讓


     它保持一致性。


 


 (e) Types safe for use in userspace.


 (e) 為了在userspace使用安全的資料型別


 


     In certain structures which are visible to userspace, we cannot


     require C99 types and cannot use the 'u32' form above. Thus, we


     use __u32 and similar types in all structures which are shared


     with userspace.


     在某些userspace可見之structure中,我們無法要求C99 types


     也無法使用 'u32' 。因此,我們使用__u32和類似的型態於所有與


     userspace共有的structure中。


 


Maybe there are other cases too, but the rule should basically be to NEVER EVER use a typedef unless you can clearly match one of those rules.


或許也有其他一樣的情況,但是規則應該基本上是從未使用typedef,除非你能清楚與那些規章之一相配。


 


In general, a pointer, or a struct that has elements that can reasonably be directly accessed should _never_ be a typedef.


一般而言,指標或是資料結構中的元素能被合理的直接存取而且 _決不_ 是一個typedef


 


 




 


         Chapter 6: Functions


         6: 函式


 


Functions should be short and sweet, and do just one thing.  They should fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24, as we all know), and do one thing and do that well.


函式必須短小可愛並且只做一件事它們應該能夠塞進一或兩頁的螢幕裡去 (我們都知道ISO/ANSI標準螢幕大小是80x24) 且只做一件事並且要做的好


 


The maximum length of a function is inversely proportional to the complexity and indentation level of that function.  So, if you have a conceptually simple function that is just one long (but simple) case-statement, where you have to do lots of small things for a lot of different cases, it's OK to have a longer function.


一個函式的 (可允許的) 最大長度是和其複雜度及縮排的程度成反比所以如果你有一個觀念上簡單的函式卻是一個長的 (但是簡單的) case敘述其中你須要對許多不同的情況做許多的小處理那麼函式長一點沒有關係


 


However, if you have a complex function, and you suspect that a less-than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely.  Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it's performance-critical, and it will probably do a better job of it than you would have done).


不過如果你有一個複雜的函式而你覺得可能一般程度的高一學生就無法瞭解這個函式在幹麻你可能更需要更嚴格的遵守最大長度的限制使用名字較有意義的輔助函式 (helper functions) (如果這個函式對效率的要求很高的話你可以要求編譯器把這些輔助函式當作in-line function展開而且編譯器可能可以做的比你自己手工做來的好)


 


Another measure of the function is the number of local variables.  They shouldn't exceed 5-10, or you're doing something wrong.  Re-think the function, and split it into smaller pieces.  A human brain can generally easily keep track of about 7 different things, anything more and it gets confused.  You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now.


另外一個評量函式的方法是區域變數的數量它們不應該超過5-10不然你可能做錯了什麼事重新構思一下這個函式然後把它切成幾個小塊人腦一般可以輕易的處理七件事超過這個數量就會搞亂了你知道你很聰明但是兩個禮拜後你可能還想瞭解你現在做了什麼


 


In source files, separate functions with one blank line.  If the function is exported, the EXPORT* macro for it should follow immediately after the closing function brace line.  E.g.:


在程式碼檔案裡,不同的函式用一條空白的行分開。如果函式有被其他的檔案參考到,則EXPORT* 巨集必須緊緊跟隨在函式的右大括號之後。如:


 


int system_is_up(void)


{


    return system_state == SYSTEM_RUNNING;


}


EXPORT_SYMBOL(system_is_up);


 


In function prototypes, include parameter names with their data types. Although this is not required by the C language, it is preferred in Linux because it is a simple way to add valuable information for the reader.


在函式的原型裡,必須包含了參數名稱以及它們的資料型別。雖然C語言沒有這樣要求,但在Linux的程式碼中是喜歡如此做的,因為這是增加有價值的資訊給讀者的一種簡單方法。

arrow
arrow
    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()