2019年9月26日

[筆記] port list can be ( , , ... , ) in SystemVerilog

最近在讀 SystemVerlog 的 LRM,發現裡面的語法允許某個很神奇的寫法:
module MM ( , , ,); ...
沒錯,port list 可以是一堆 , 沒有任何名稱! 雖然 LRM 的 syntax 確實允許這樣寫,但會允許是空的真的很奇怪

2019年9月6日

[筆記] Codeforces 1208D. Restore Permutation

[題意] 給一串 n 個數字的序列 $s_1, s_2, s_3, ... , s_n$,要找出 1 ~ n 這 n 個正整數的排列 $p_1, p_2, ... , p_n$ 使得 $s_i = \sum_{j=1}^{i} p_j$,其中 $p_j < p_i$

2019年8月31日

[筆記] Codeforces 1208A: XORinacci

[題意] 其實就是算 Fibonacci number,只是原本是 $F(n) = F(n-1) + F(n-2)$ 變成了 $F(n) = F(n-1) ⊕ F(n-2)$,其中 ⊕ 是 bitwise xor 運算,並且 F(0)及 F(1) 是題目給定而不是定值。

[筆記] Codeforces 1208B: List Of Integers

[題意] 給一個正整數 n ($1 \leq n \leq 2000$) ,後面接著 n 正整數 $a_1, a_2, ... , a_i, ..., a_n$ ($1 \leq a_i \leq 10^9$),請找出一個這數列的一段連續區間使得這 n 個數字拿掉這段區間後的數字皆不重複。答案要找的是這段區間最小的長度是多少

2019年6月4日

[C++] std::stringstream cannot output integral type

這次遇到的問題簡單來說就是不知道為什麼程式的 log 有部分訊息被吃掉,然後整份 log 就此大亂。細追分析後發現我們的 log 會先用 std::stringstream 把使用者傳進來的所有參數 (任意數量 & 型態) 轉成 std::string,隨後才把他輸出到 log file 去,而在 std::stringstream 試圖要處裡一個數值型態的參數時會丟出 exception,雖然會被他自己吃掉不會往上丟,但也導致要處理後面的參數時運作情形就不如預期。

進一步往下追原因的時候發現這其實是所有繼承 std::ios_base 的類別都會有的狀況,原因的話簡單來說就是 std::ios_base 內部會主動去處理 locale 相關問題,在這過程中的檢查出狀況時就會丟出一個 exception,而這個 exception 雖然馬上會被吃掉,但會拉起內部的 badbit,下一次要 output 時因為 badbit 被拉起來了,所以會吃掉丟進來的參數但不會真的印出去。

2019年4月28日

[C++] Deep into Hash Map in STL: std::unordered_map

std::unordered_map 是 C++11 後 STL 新增的 container,本質上可以想成是一個 hash map。相較於原先的 std::map 基本上是個 red-black tree , std::unordered_map 的重點在於許多操作的 amortize complexity 基本上是 constant time。只是使用上有些許的重點要注意,不然效能可能會不如預期

2019年3月28日

[筆記] High CPU Usage on Windows 10 Event Log (svhost.exe)

公司筆電自從某次 windows 10 更新後 CPU 使用率一直高居不下,然後風扇就一直轉吵死人,每次一開會拔掉電源就撐不了多久實在很惱人。本來開工作管理員一直看到 windows event log 想說可能是 windows 本身不知道幹了啥事就先不理他,結果過了一周完全沒改善只好去查原因,花了一個多小時才終於查到問題點 = =

2019年3月26日

[C] Variadic Macro

有時候會有個需求是像這樣:
  • 希望在執行任何 function / expression 前可以先做檢查,檢查過了才真的執行
  • 能把上述的檢查包成容易使用的形式,讓後續使用的人不會忘記
這種需求其實很常見,以 C 來說,確保一個 pointer 不是 null 後才真的拿來用是很基本的事情。所以如果可以包成像下面的形式想必會好用很多也比較不會忘記:

#define CHECK_AND_USE(x, ...) if (x) { x(...); }

typedef void (*f1ptr)(int);
typedef void (*f2ptr)(double, const char*);
f1ptr p1 = NULL;
f2ptr p2 = NULL;
CHECK_AND_USE(p1, 2) // equivalent to if (p1) { p1(2); }
CHECK_AND_USE(p2, 1.0, "test") // equivalent to if (p2) { p2(1.0, "test"); }

這樣基本上只要記得都透過 CHECK_AND_USE 就能避免用 pointer 前忘記先做 null check。重點來了:CHECK_AND_USE 中的 ... 該怎麼辦呢?顯然的,我們需要不定數量與型態的參數。而能達到這件事情的有幾個方式,這邊要介紹的是 C99 開始支援的 Variadic Macro

2019年2月27日

[python] Inheritance & Hack with mock

最近工作的內容因為會用到 python,不過因為 python 實在太過自由了,有些特性對於習慣寫 C++的我來說實在有點不好控制,導致寫好的檢查是有可能被使用者繞過去的,舉例來說,確認使用者是否有 licesce 這件事就極度重要。這邊就筆記一些目前有想到的方式

[C++] One Simple Trick For Reducing Code Bloat

簡單整理一下這部影片的重點,說明有時候一個小動作會讓 compiler 難以最佳化,然後 code size 就會變大。

2019年2月24日

[C++] How to Write Reliable Code

這篇只是下面這段演講的整理
How to write more reliable code - Egor Bredikhin - Meeting C++ 2018
投影片

總結來說有以下這幾點
  • Guidelines
  • Unit tests 
  • Code reviews
  • Static analysis
  • Dynamic analysis
  • Mordern C++

2019年2月18日

[C++] pinned_vector - Pointer Invalidation Issue on std::vector

pointer invalidation 在 C++ container 是個滿重要 (但很容易被忽略) 的議題,主要原因在於 C++ container 會自己在 runtime 依據使用情況去調整記憶體使用量。也因此,如果用 pointer 去存取 container 中的東西時有時會遇上 container 因為你的操作 (比方說新增/刪除) 導致既有的 pointer 不再合法 (也就是原本指到的地方已經不再是你原本指向的東西,可能已經變成其他的東西或是不能被存取了),這就是所謂的 pointer invalidation,在 C++ reference 上各個 container 的 member function 其實可以看到會有一段在描述 iterator validity,那個就是在講這個議題。

當然,不同方式的 container 在 pointer validity 會有不同的情況 (比方說 std::list 沒有這問題,但是他的 element 就不會是在連續的記憶體上),選用 std container 的時候其實有一部份是要謹慎考量這問題的,因為這攸關使用情境以及效能。這次在 Meeting C++ 2018 看到的 pinned_vector 簡單來說就是提出一個可以滿足最低限度的 pointer validity 的改良版 std::vector