January 12, 2006

真的理解 C 語言的 types 嗎?

拜讀葉博士的 blog [南柯一夢二十年],那句話總是徘徊於內心深處:
    遇到這樣的個案:
    • 第一堂課:「我有 20 年的工作經驗。」
    • 最後一堂:「現在我才發現,我只有 1 年的工作經驗,只不過重複了 20 年。」
    但願退休的那一天,我不會發出同樣的喟嘆。
從國中接觸 C 語言程式設計以來,我知道工具只是協助人們解決問題,重點還是在於如何去克服問題,陸續撰寫了中小型的軟體專案,也包含簡單的 C++ subset compiler,稍加閱讀 ANSI C Standard 後,曾有一度認為自己懂了 C 語言,然而長大後,才知道當時的無知與愚昧。

剛剛閱讀 Peter Seebach (ISO C committee) 撰寫的入門文章 [Everything you ever wanted to know about C types, Part 1: What's in a type?],裡面沒有艱澀的技術,只有我們熟悉的 C89/C99 Standard,然而,有些細節甚至讓我花了一段時間查證,我開始懷疑:
    「是否,我只有一個月的 Programming 經驗,只不過重複了好幾個月?」
該文從 C types 出發,先提及幾個經典的議題,像是 +/- sign 表示、補數表示、IEEE 浮點表示、在 C89/C99 中負值算術的差異與爭議處、極值表示、影響最佳化的 types、volatile / restrict qualifier,以及在 C 語言中實做資料封裝的概念,篇幅不長,但每個議題後面都可以找到許多引證與陷阱案例。舉例來說,文中提到 C99 中考慮到 compiler optimizations,在 "A new meaning for static" 提到以下的宣告:
    void foo(int a[static 16]);
vectorization 在近代的 compilation optimization 是很重要的議題,在之前的 blog [C-style 字串的最佳化] 可以發現 int a[] 的 object layout,而多數的指令集也提供了 16 (含以上) pipelines 的 SIMDs,有很大的最佳化空間。不過 C 語言的常見陷阱就是 array indexing 的範圍,是有高度的自由,當然,在特定的 C compiler 對此會作些規範,比方說 TI DSP core 專用的 compiler 就伴隨了許多描述用的語法,表示 Runtime 的 indexing 坐落範圍。

再來是經典的 volitile 與 restrict qualifier,這在多數的 interview 會考到,我甚至可以把 ISO C Standard 裡面的定義背出一部分,然而,我真的懂嗎?在開始 trace Linux kernel device driver 後,才發現 volitile 以及 GCC optimization 造成的影響是相當大的,而且會引來相當 tricky 的效應。打開 /usr/include/string.h 可以發現以下兩個宣告:
    __BEGIN_NAMESPACE_STD
    /* Copy N bytes of SRC to DEST.  */                                  
    extern void *memcpy (void *__restrict __dest,                
                         __const void *__restrict __src, size_t __n)
         __THROW __nonnull ((1, 2));                                     
    /* Copy N bytes of SRC to DEST, guaranteeing
       correct behavior for overlapping strings.  */                       
    extern void *memmove (void *__dest, __const void *__src, size_t __n)
         __THROW __nonnull ((1, 2));                                    
    __END_NAMESPACE_STD
    
memcpy(3) 與 memmove(3) 在語意上最大的差異,就是允許 overlap 與否,這是為何 C99 中,兩者引數有不同 prototype 的緣故。Peter Seebach 在這系列的文章尚有三篇,想必可引來更多的思索,在此同時,如果不想在工作二十年後自嘆「我只有 1 年的工作經驗,只不過重複了 20 年。」,還是多觀察案例,多作思索並動手作,自勉之!
由 jserv 發表於 January 12, 2006 06:01 PM
迴響
發表迴響









記住我的資訊?