目前分類:C&C++ (51)

瀏覽方式: 標題列表 簡短摘要

本文的前身〈純手工安裝msys〉內容過時且凌亂無章,這裡重新以 mingw-get 為基礎重寫。

對於只是單純想要有個 Win32 版 GCC 的使用者,使用官網或TDM的圖形界面安裝程式即可。官網的圖形界面安裝程式也能順便安裝 MSYS,但使用命令列界面有比較大的彈性,我使用mingw-get的原因是:

novus 發表在 痞客邦 留言(3) 人氣()

去年底有很長一段時間沒在這裡寫東西了,部分原因是我在 wikibooks 發起《CMake 入門》一書。雖然距離完成還很遠,但我已經漸漸失去動力,日後應該只是偶爾加些內容而已。如果網友對這方面有所涉獵,不妨幫忙補充或修正錯誤。

最初我只打算寫幾個範例在這裡發表,不過寫著寫著卻覺得部落格真不是發表這種東西的地方,後來想到 wikibooks 或許是個合適的發表點。但等到我把內容轉到維基教科書時,卻發現內容不停的擴充,超出我的想像。畢竟在部落格可以隨便亂寫,給自己備忘、讓其他人亂猜,不過寫成詳細的教學卻不得不加入細節。或許過一陣子有空,我會考慮濃縮成精華版回貼到部落格上(我對這點不掛任何保證)。

novus 發表在 痞客邦 留言(1) 人氣()

在去年初玩了一下 Google Test,雖然我還蠻喜歡他的簡潔性,不過仍然繼續用 Boost.Test,一來是因為在我使用的電腦 Boost 可得性比較高,二來是因為當時只能在 Visual C++ 下面使用,用 MinGW 編譯有點問題。

虧我個人的 MSYS 和 MinGW 工具裝得相當齊全,但是執行 configure、make 卻不太成功,我也沒有閒功夫去追原因為何。

novus 發表在 痞客邦 留言(0) 人氣()

前幾篇我介紹了一種不用 __VA_ARGS__ 實作可變參數 macro 的方式,例如可以這樣寫

PRINTF("%d %f %s", (1)(3.14)("hello"));

novus 發表在 痞客邦 留言(0) 人氣()

在程式撰寫過程中,有時候我們會希望輸出一些內部的資訊,例如某某變數值是多少、有沒有進入某某函式等等,讓 debug 有線索可循。很多人的做法是直接在程式碼當中插入 printf 或 cout,到正式 build 的時候再手動將這些資訊移除,這種做法只適用於小規模的程式,並且在 GUI 程式比較難用。比較巧妙一點的做法是將相關的功能用 macro 包裝,靠 NDEBUG 或類似的 flag 來決定是否輸出這些除錯資訊。我記得 VB6 有個類似的功能叫做 Debug.Print,正式建置程式的時候這些指令將會被編譯器忽略。

以前我的做法是把一些常用的 debug 和 assertion 功能用 macro 包裝好塞在一個標頭檔裡面,依照現實需求略做修改,通常這樣就已經很夠用了,所以未曾在此多留心。後來我在《Applied C++: Practical Techniques for Building Better Software》讀到了一種複雜許多的 debug output 方法,才知道原來小題也可以大作到這種地步。複雜帶來的是功能上的彈性,例如在書中介紹的機制只要切換一個叫做「Debug Sink」的組件,就可以將蒐集到的資訊全部倒到 console、檔案、訊息視窗甚至是網路。不過這些額外的好處還不夠吸引我,所以我還是繼續使用自製的 macro 工具。

novus 發表在 痞客邦 留言(1) 人氣()

最近 survey 了一些 debug sink 實作,其中最原始的應該是 dprintf。用函數實作的dprintf有一些缺點,例如 releas build 時編譯器仍然無法去除額外的函式呼叫。另一方面我們希望能夠自動收集 __FILE__、__LINE__ 的資訊,節省機械化的打字。

要解決這個問題其實很簡單,這裡提供一種做法

novus 發表在 痞客邦 留言(0) 人氣()

先聲明,這不是教學,只是將個人見聞記錄下來,希望對其他人有用,也希望有高手能針對錯誤的地方 給予指正,沒有經驗的人應該先去找個真正的教學來看。

這裡以 MinGW 4.5 建置其他 GCC 4.x toolchain 為範例,GCC 3.x 雖然步驟差不多,但有些小地方應 該要修改。我選的 target 是 arm-elf,因為我對這個比較熟,其他目標有的需要 target system header 比較麻煩。

novus 發表在 痞客邦 留言(1) 人氣()

用 GCC 4.5 編譯 Boost 1.44 遇到第一件感到猶豫的事,就是 runtime-link 該用 static 還是 shared。在 VC 通常想都不用想就選 shared,然後發動坊間熱賣的白癡念力術,妄想其他電腦都出現正確版本 VC runtime。

在 GCC 4.4 之前,MinGW 對標準程式庫都是預設為 static,而且 libstdc++ 還在可接受的體積內,所以我也沒有太關心這個選項。動態連結 libgcc 和 libmingw32 似乎沒甚麼道理,靜態連結可以省掉一堆鳥事。然而見識過靜態連結libstdc++ v3 所帶來的肥大程式碼:直接 cout 出 hello world 就直逼驚人的 1 Mb,就算 strip 過還是大於 500k,如果常撰寫小程式可能得好好考慮動態連結。

novus 發表在 痞客邦 留言(3) 人氣()

在砍掉重練之前請三思:不必自宮也能成功。

2011/09/20 補充:

novus 發表在 痞客邦 留言(1) 人氣()

2011/6/5 補充

原文的內容已經過時而且過於雜亂無章,一些朋友無法依照原文指示完成安裝,因此最後決定刪除。有用的資訊已經併入〈 使用 mingw-get 安裝 MinGW 和 MSYS〉一文。

novus 發表在 痞客邦 留言(3) 人氣()

我一直沒試過在多緒環境下使用 rand() 或 strtok() 這類函數,因為古有明訓,早在我對 thread 都還沒有什麼概念之前,就已經知道 rand() 或 strtok() 最初設計時對多緒環境完全盲目,所以這種用法對我來說是根本都不用考慮的愚蠢行為。另一方面是因為手邊有比 rand() 和 strtok() 更強而有力的工具,所以甚至是普通的單緒程式我都不太喜歡用 rand() 和 strtok()。

這些函數在多緒環境的問題很容易理解,例如 rand() 通常用線性同餘法實作,內部要維護一個長期存在的種子以產生下一個數。麻煩的地方在於,在多緒環境下呼叫這些函數,可能導致於同時競爭讀寫這些記憶體。同樣的問題也發生在 strtok 上。

novus 發表在 痞客邦 留言(2) 人氣()

C/C++ 當中有一派人士認為,當一個東西不該出現負值的時候,應盡可能以 unsigned 修飾。舉凡標準程式庫當中與記憶體大小相關的數值,像 sizeof 運算、size_t、還有STL容器的 size_type 都是某種 unsigned 整數類型;其他像 strlen 的回傳值以及 malloc 的輸入值也都具有 unsigned 性質。

除此之外,有些人更進一步主張像年齡、人數之類的,既然永遠不可能為負值,那麼也應該要加上 unsigned 關鍵字。這麼做最主要的好處之一是可以在宣告當中表明意圖,另一方面既然 unsigned 不可能為負,所以檢查有效範圍會比較簡單:

novus 發表在 痞客邦 留言(0) 人氣()

本文不打算包含:如何從頭撰寫一個 DLL、如何用某某牌編譯器編譯 DLL、如何在某某牌編譯器使用DLL..... 等等議題。基礎 DLL 教學在網路上非常豐富,有需要的人應該很容易可以得到所需資源,在此先假設讀者都有一定的熟悉度。這裡只打算提供一些能稍稍增加彈性及可維護性的小經驗,特別是 DLL 的 header 方面。或許對很多人來說可能都是常識,只是我發現網路上比較少這方面的整合資訊,所以做了一點綜合整理。

以下我拿自己常用的 DLL header 範本為例

novus 發表在 痞客邦 留言(3) 人氣()

會有這個程式,是因為聽一位朋友說,他光是寫井字遊戲的AI就用掉近千行。
然後當時我就宣稱不用一百行,我就能做出含視窗介面、AI 和流程控制的井字遊戲。

novus 發表在 痞客邦 留言(4) 人氣()

大概去年底解答一位網友的問題,沒想到今天我自己也碰上了。唉,我已經很少犯這類錯誤了說。

novus 發表在 痞客邦 留言(0) 人氣()

話說最近又看到一些小朋友發問同樣的爛問題,大概是同班同學吧。

猜猜會印出什麼?

novus 發表在 痞客邦 留言(0) 人氣()

下一代的 C++ (之前的0x,現在已經變1x了)有一項我很喜歡的功能,雖然不會增加 C++ 能做的事,不過讓 C++ 更具易用性。這裡要說的是 initializer_list 和一致的初始化語法。

這份提案已經通過 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2531.pdf

novus 發表在 痞客邦 留言(1) 人氣()

最近看到某位網友的問題:「template 的函數的指標要怎麼傳給 template的函數?」由於沒有額外的說明,所以我不太確定他遇到的困難點在哪裡。

先來看看熱身題,假如存在下面程式片斷,要如何傳遞 Output1() 給 Call() 呢?:

novus 發表在 痞客邦 留言(1) 人氣()

一直以來我都是用 Boost.test 做為測試工具,這是到目前為止我唯一在現實中使用的測試工具,雖然我也試過其它的 test framework,不過僅止於跑跑簡單的範例而已。

這倒不是因為 Boost.test 有多出色,而是因為我的開發環境都灌了 Boost,所以 Boost.test 對我而言是最容易取得的選擇,而且還不算太難用。

novus 發表在 痞客邦 留言(0) 人氣()

前幾天,我在常逛的論壇上看到有人這樣寫 C++ 的 delete:

delete p1, p2, p3;

 

novus 發表在 痞客邦 留言(1) 人氣()

«12 3