The Lost Art of C Structure Packing

找 C/C++ padding 資料時找到的文章:The Lost Art of C Structure Packing

講解 C/C++ struct padding 講的很仔細。C/C++ 編譯器會為了記憶體對齊而把變數放到偶數位址上,放到偶數位址上的好處是存取快速,而且編譯出來的指令也較少。但像 char 型態的變數佔用的空間不一定會是偶數,所以為了對齊而空出來的空間就是所謂的 padding。例如:

裏面的 pad 就是浪費掉的空間。

除了 padding 還有提到 pack,我以前對 pack 也不太了解。看完這篇才知道 pack 的意思,pack 就是告訴編譯器說,不要把變數對齊到偶數的位址上,當然,這樣做之後,編譯器就不會作 padding,但代價就是效能。在 gcc 裡,用 #pragma pack 就可以。

最後作者的建議就是:

  1. 除非你知道自己在做什麼,否則沒必要使用 pack。
  2. 安排 struct 成員時,先放指標類成員,再依照型態所佔用的空間大小來依序擺放,這樣可以避免不必要的 padding。

Feednix on Ubuntu 12.04

在 OMB! Ubuntu! 上看到 Feednix : Feednix is a Command Line RSS Reader for Feedly,這是用 C++ 開發的 terminal feedly client。目前還沒看到 PPA,就只能自行編譯了。

我的環境是 Ubuntu 12.04。

原始碼可以從 Jarkore/Feednix 這裡取得,裏面沒有提供 ./configure,所以得先輸入 ./autogen.sh,這裡會先告知你需要 autoconf 2.69,但 Ubuntu 12.04 只有 autoconf 2.68。要解決這個問題,得修改 configure.ac 的第一行,把 2.69 改為 2.68,並且重新執行 autoconf。

接著要安裝相依的函式庫標頭檔:libjsoncpp-dev, libcurl4-openssl-dev, libncurses5-dev,這些用 apt-get install 安裝即可。執行 ./configure 可以產生 Makefile,但編譯時會有 unrecognized command line option 「-std=c++11」的錯誤而無法編譯,這是由於 12.04 配的 gcc 版本過舊的關係。針對這問題,我改用 clang 來編譯:./configure CC=clang CXX=clang++  (用 sudo apt-get install clang)。

編譯的過程裡,還是有 PostData({….}) 無法初使化的編譯錯誤,這應該是 C++11 的新寫法,但 clang 不認可,那就只能改寫為比較不酷的寫法。

這樣就可以編譯通過,並產生出執行檔了。但最後執行,輸入完帳號跟密碼,仍會有 Segmentation fault 的問題。

PokerTH 0.4 編譯問題

環境:Ubuntu 12.04

下載 PokerTH 0.4 版來編譯,QT 的系統都是要先打 qmake 來產生 Makefile:

qmake
make

結果會出現錯誤

‘class boost::detail::try_lock_wrapper<boost::timed_mutex>’ has no member named ‘locked’

12.04 有 3 個 libboost-thread 版本:1.46, 1.48, 1.49 ,試過以後都不行。

直接去 /usr/include/boost/thread 看,原來是沒有 locked() method,去 src/core/common/thread.cpp 裡,將使用 locked() 函式的地方修改為 owns_lock() 就可以編譯了。

Lex 練習

看 lex & yacc 第一章的練習,然後改用 glib 的 GList 來做:

Lex 是用來 tokenize 輸入用的,也就是用來辨識說輸入裡有哪些東西是你要的。這個例子書上沒針對怎麼使用做解說,乍看之下,不容易懂。其實使用上就是打 verb is,表明說 is 是 verb,你可以一直輸入 verb read、verb write、noun book、noun dog….程式就會把你輸入的這些內容分類、放到list裏面去,之後你輸入 read、write、book 時,程式就會告訴你 read、write 是 verb,book 是 noun 。

改用 glib,是因為想練習 glib。g_list_find_custom令人意外地沒範例,不過用法挺簡單,主要變化在第二個參數,第二個參數是一個 function。該 function 第一個參數是 list 裡的元素,第二個參數就是 g_list_find_custom 裡的第二個參數,你可以參考 compare_word,應該是不難懂。
參考資料: