星期五, 11月 01, 2013

同時轉型又宣告之神秘的 C

不但可以邊 casting 邊宣告,宣告玩之後還能繼續使用!
不過 gcc 跟 g++ 編譯器的行為不太一樣就是了,g++ 並不會直接給你過關。
code 寫久了,網上的技術文章逛久了,就會發現很多小惡魔小細節,是藏在編譯器裡面。




struct x { 
    int xx; 
};

int main()
{
    struct x data;
    data.xx = 99; 
    struct x *tmp = &data;

    printf("tmp->xx = %d \n", tmp->xx);
    printf("(!#$^&)->yy = %d \n", ((struct y {int yy;} *)(tmp))->yy);
    
    struct y xxxx; // Also can be used later!

    // Change *.cpp will have different result
    // gcc will select the correct back-end compiler based on file extension 
    // In c++: error: types may not be defined in casts

    return 0;
}

星期三, 10月 30, 2013

預防笨錯誤? 尤達表示法 (Yoda Condition)

曾幾何時,在公司的程式碼看到一段code,以下為示意:
if (TRUE == isOilPoisonous)
{
  printf("It's Da Tung!");
}
產生很多問號,誰吃飽撐著把 TRUE 放在比較式的左邊呢?
是為了強調這段程式碼的意圖嗎?

事實似乎不是這麼一回事!

直到最近,才知道這東西叫做尤達表示法 (Yoda Condition)。
他存在的目的完全不是為了可讀性,相反的,這種風格使可讀性下降了。
那為什麼要付出代價維持這種風格呢?

原因如下。
看看這兩段程式碼,毫無疑問完全相同,只是條件順序對調了一下。

if (isOilPoisonous == TRUE)
{
  printf("It's Da Tung!");
}

if (TRUE == isOilPoisonous)
{
  printf("It's Da Tung!");
}

但是如果有人手抖把 "==" 敲成 "=" 的時候,你會發現,其中只有一種會compile error。
而另一個,會巧妙的隱藏,成功地編譯,變成很難發現的臭蟲。
日常生活中,手抖,手殘,以及少打一個等號這種事情,是絕對有可能發生的。
為了避免這種情況,只好犧牲一些可讀性,套用 Yoda Condition,來斃掉這種藏得很深的臭蟲。

事實上,現在的 compiler 可以讓你察覺這種手抖的情況。
用 gcc version 4.4.5 測試了一下,如果你有使用 "-Wall" 參數,
來編譯 "if (isOilPoisonous = TRUE && ...) ...",
你會得到這樣的警告訊息:
yoda.c:7: warning: suggest parentheses around assignment used as truth value
但如果進一步改寫成這樣 "if ((isOilPoisonous = TRUE) && ...) ...",就...

註:尤達大師講話愛用倒裝句。

參考:http://en.wikipedia.org/wiki/Yoda_conditions

星期五, 9月 20, 2013

Honey Moon

嚴格來說,這是第三次到夏威夷了,第一次年紀太小,停留時間也太短沒太多記憶。第二次去參加 conference ,玩樂的時間有點稀少,也是有點可惜。這一次蜜月終於玩了三個島,花了十天,滿過癮了。不過沒有達到預期的小麥色肌膚,稍嫌不足。

在Oahu Island 的 Hanauma Bay (恐龍灣),原本Hanauma Bay 命名自於海灣的弧形,至於恐龍指的應該是右側延伸至海裡的小山,形狀像是一隻臥躺的恐龍,這部分應該後人的旅遊成分添加物。其實這個海灣是一個火山口!這裡應該是整個夏威夷最適合浮淺的地方吧,帶個蛙鏡,買個小泳圈,下水就對了,整個淺灘延伸的距離很長,優游自在。