2018年8月24日

[C++] Lazy Evaluation for Function Argument

C++ 的 function call 在傳參數進去時基於一些因素會把所有參數都拿到最後的結果後才進入 function 本體去執行。比方說,傳進去的參數是一串四則運算時,會先算出最後的結果;如果也是個 function call,那也會先把 function call 執行完畢拿到結果。

在某些情況下如果我們知道其實進入 function 後根本不會用到這些參數的內容時,做這些計算其實就會變成浪費時間了。因此,最容易想到的解法是,有沒有辦法把這些運算的過程延遲到我真的需要時才讓他執行?

2018年8月21日

[C++] Use std::condition_variable for Parallellism

C++11 開始 STL 就提供了 thread library以便寫平行化的程式,condition variable 簡單來說就是用來控制流程用的,他允許我們在過程中透過 condition variable 來決定是否要 block 某個 thread 等待另一個 thread 完成工作,也可以透過 notify 去讓一個 (或多個) 正在等待 thread 繼續往下執行他們的工作。

2018年8月9日

[C++] Compile-Time if in C++17 Can Have Code Not Able to Be Compiled with Regular Runtime if

Compile-time if 在 C++17 中也算是一個滿有趣的特色,其特點就在於能夠在 compile time 就幫你確認清楚 if statement 中會執行到哪一個判斷式對應到的區塊,從而把其他一定不會用到的區塊 "拔掉"。這點在現在電腦上算是個滿有用的特色,畢竟現在 CPU 的 branch prediction 一定錯誤通常都要承擔不小的後果 (註) 

原本我以為 compile-time if 只是針對一些能在 compile-time 就能推知結果的運算做優化 (特別是在 template 上),結果今天看到一個例子才發現這玩意兒比想像中更猛,甚至能夠寫出一些原本 regular runtime if 做不到的功能。

2018年7月17日

[筆記] 狂歡西班牙 - 上課筆記

事情是這樣的,有一天在 Coucou穀穀你好 法式小食舖 上看到老闆娘為眾人著想(想不開)跟 Mia 老師 合作要開課,教的內容有包含前菜、主菜、甜點各一道。想說機會難得就找了一堂課去上了,所以下面就是上課的內容跟一些簡單筆記了。

2018年7月2日

[筆記] google perftools (gperftools) - 安裝與超簡易使用說明

google perftools 簡單來說就是一套用來做 memory 跟 CPU (也就是 runtime) 的 profiling tool,基本用途有三個:heap profile,單純每個看 component 的 memory 使用量;heap checker,用來檢查有沒有 memory leak;以及 CPU profile,用 sampling 的方式去探測 CPU 的使用量。這東西最大的優點就是幾乎沒有 overhead。所以比起直接用 valgrind 去跑,可以考慮先用 gperftools 先做簡單的 profiling 粗略掃描,有必要更深入檢測的話再丟給 valgrind/callgrind 去細部檢查。

2018年6月26日

[C++] prvalue sucks!

最近在看 YouTube 上的這部影片解釋 object, lifetime 還有 reference 相關的內容,裡面有個有個關於 prvalue 的範例讓我有點驚訝,驚訝地點在於 C++ standard 對於標準有定義的型態 (像是 primitive type) 跟未定義的型態 (像是 struct 或是 class) 有完全不一樣的行為,但為什麼會這樣定義卻想不通 = =

2018年5月25日

[C++] 利用 generic progamming 簡化存取 union 變數的介面

公司的程式 (特別是那種底層 API) 其實很常使用 union 來減少非必要的記憶體使用量,只是如果使用 union 的話就必須要能夠知道該用哪種型別來存取 union 中的變數,因此很常出現這種程式碼:

enum Type {Int, Double};

struct Data {
    Type type;
    union {
        int i;
        double d;
    };
};

int main()
{
    Data data;

    data.type = Int;
    data.i = 3;

    data.type = Double;
    data.d = 3.14;

    return ;
}

簡單來說就是設定好要存取的是哪種型態 (然後用個 enum 來表示),接著 API 會根據設定的型態來對 union 中的變數做存取。以上面的範例來說,會根據 Data 中的 type 是被設定成 Int 還是 Double 來決定 是要存取 data.i 還是 data.d

因為個人覺得這樣滿容易手殘的,特別是公司的 API 其實型別種類有點多 |||Orz,所以想要簡化 API 的使用方式,希望可以直接根據所設定的型別存取對應的變數就好,畢竟這種關聯性其實是固定的,利用 generic programming 應該是不難做到的。

2018年5月23日

[C++] static_cast & reinterpret_cast & C-style type cast

C 的型態轉換大家應該都很熟也很常用,不過在 C++ 中因為 C++ 的功能與語言特性複雜許多,C 語法的型態轉換一來不易辨識,二來其內部運作方式較為隱晦不清,因此 C++ 引入了四種型態轉換運算子,分別是
static_cast, dynamic_cast, const_cast 與 reinterpret_cast
大多數情況我們所使用的 C 型別轉換通常是對應到 static_cast;dynamic_cast 則是應用到繼承體系的型別上;const_cast 其作用只在於拔掉變數的常數性 (const) 與揮發性 (volatile),其餘維持不變;其中最玄的該數 reinterpret_cast 了,有部分 C 的型態轉換的使用情形對應過來 C++ 這邊其實是要用 reinterpret_cast

2018年5月22日

[C++] fold expression

fold expression 是 C++17 中專為 variadic template (或者說 parameter pack) 設計的東西。

2018年5月7日

[C++] move semantic 的誤解

今天部門的讀書會上討論到 Effective Modern C++ 中介紹關於 C++11 開始引入的各項新特色與其相關問題,其中有個例子介紹到了 std::move 跟 std::forward 的使用時機。主講者也很有心的把其中某個例子自己嘗試寫了出來並加以變化來驗證,結果沒想到剛好可以變成一個說明何時不該使用 move semantic 的絕佳範例 XD 而且這也剛好說明了 C++11 引入了各項特色其實還...滿難懂的,也難怪會後會有人說其實乾脆不要用就沒這些煩惱。