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

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

前幾天有網友回覆 四則運算解析器 那篇,回頭瞄了一下舊程式碼剛好讓我得到了一個靈感,所以寫了這篇「函數解析器」。

我過去曾用 C++03 實作過一些小型語言的編譯器、直譯器,使用都是比較傳統的方法,也就是設計一個 AST 節點的基礎類別,再特化出各種不同類型的 AST 節點。這個寫法非常的囉唆,許多程式碼都是為了滿足靜態型別語言的規範,而不是實現真正的功能,相較之下 python、javascript 之類的語言可以用精簡許多的程式碼完成同樣的事情。

文章標籤

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

在排序固定長度的小陣列時,那些 big-O 優異的演算法往往討不到便宜,而且還很容易因為多餘的操作而拖慢速度。Sorting Network 就是為了排序固定長度的小陣列而發明的。Sorting Network 是一組事先規劃好的比較、交換操作,只要按照固定步驟操作就能將資料排序。

若一個 Sorting Network 滿足某些條件,就可以將操作步驟平行化或者實作成平行排序硬體,這是這類演算法最大的優勢,不過這不是本文的重點。即使在沒有平行化的情況下,Sorting Network 作為循序執行的排序法效能通常也不錯,至少可以狂電 Bubble、Insertion sort,而且所有的動作都是固定的,可以輕易寫成一連串無迴圈的 if-swap 串,這在「big-O不代表一切」的小資料世界裡具有實作優勢。

文章標籤

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

今天和同事聊到「真搞不懂為什麼某些人那麼容易中毒?」這個話題時,剛好心血來潮,順手示範了一個從前曾拿來整人用的老把戲。

這個把戲就是用 linker 把某個二進制資料嵌入到執行檔中,變成其中一個區段。當然,其中沒什麼高深的學問,只是因為很多人沒有仔細玩過 binutils,不曉得 ld 有這樣的功能。

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

今天有位幫一位朋友釐清觀念的時候,發現他對物件的記憶體分配有些誤解。這位朋友告訴我他的資訊來源是這個網頁:

http://ot-note.logdown.com/posts/173174/note-cpp-named-type-convertion

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

C++14 都出來了,C++11 仍然有很多東西我沒有好好吸收,主要是因為在現實中沒有什麼使用機會,只是在閒暇時囫圇吞棗般看了一堆文章而已。舉例來說,inline namespace 就是一個我最近才仔細研究使用情境的機制。

C++11 的 inline namespace 主要功能在於,讓撰寫者可以在 namespace 建立抽象層,在底層切換不同版本。

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

之所以會有這篇文章,源於前天發生的一件笨事。我正在為手邊新專案撰寫 CMakeLists,結果在編譯某個 DLL 的時候出現錯誤,主要的訊息是一堆 "Undefined reference to..."。

我對這類的玩意還算蠻有經驗的,快速確定了該連結的東西都有寫到,剩下比較有可能的大概就是連結順序的問題。但這實在不太可能發生,我一向非常留意這些細節。

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

有一個很簡單的需求,一開始我以為對 Boost.Log 這樣功能強大的程式庫應該輕而易舉,結果花了我一點時間才摸出門徑。條件是這樣子的:

  • 必須支援命令列和檔案輸出。
  • 在支援 ANSI color code 的環境中,允許使用者啟用彩色輸出,程式會依照 log record 的 severity level 改變輸出顏色。
  • 若環境不支援 ANSI color code,程式不應該輸出色彩,否則可讀性會慘遭 ANSI color code 破壞。
  • 無論如何檔案都不應該輸出 ANSI color code,理由同上,更何況各家的 log viewer 都已經有自動上色的功能了。

假設既有的片段如下,為了簡短起見,一些細節被我簡化了,這不是隨貼即用程式碼。

文章標籤

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

大概兩週前有位網友在調查有多少人了解下面這個宣告式:

unsigned int n = -1;

我看到這個問題的時候,已經有不少人實驗得出結果,並且也開始討論這段程式碼的風格問題。以上程式碼的作用在於將 n 所有 bit 設為 1,這是一個非常可靠的行為 -- C 和 C++ 語言標準中對由 signed 到 unsigned 的轉型有段謎語般的詳盡敘述,事實上在採用 2 補數的環境中,所謂轉型的實質行為就只是把位元照搬過去而已(至於採用其他數字系統的平台太罕見,以下不討論)。

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

假設程式需要用到三個演算法,分別是 Foo、Bar、Qwerty,每個演算法可能會有 64-bit 整數、32-bit 整數、SSE2、SSE3 等四種實作方式。

在 32-bit 編譯環境上,通常 32-bit 版本會比 64-bit 版還快,且 SSE 版還會比原生整數更快;反過來說,在 64-bit 編譯環境應當優先使用 64-bit 整數版。基於懶人因素以及現實考量,大部分的演算法在一開始並不會有 SSE 版,只有當現有演算法還有顯著改善空間時,才有足夠的誘因去實作 SSE 版。最後,並非所有平台都支援 SSE,因此必須適時關閉這部份實作。

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

不熟悉浮點數的人最容易犯的錯誤之一,就是直接用 == 或 != 比較兩個浮點數。以最常見的 IEEE 754 浮點數來說,下面這樣的判斷式竟然不成立:

if (0.1 + 0.2 == 0.3)

原因在於以二進位表示的浮點數並沒有辦法精確儲存 0.1、0.2、0.3 這些十進位實數,只能以最接近的浮點數表示,和原本的數值有微小的誤差。三個各自帶有誤差的數字要碰巧讓整個等式成立,實在是相當困難的一件事。基於同樣的理由,在採用 IEEE 754 的環境下,以下程式片段陷入無窮迴圈也就沒什麼好奇怪的了:

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

前幾天剛好逛到幾篇說明 volatile 的文章,其中有關 volatile 在多執行緒環境的應用並不很完整,這裡做一點補充。

簡單來說,volatile 的作用僅僅是告訴編譯器不要用暫存器快取變數,每次使用都必須從資料的原始來源重新載入。

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

前言

之前說過想花點整理 boost 和 C++11 當中 Smart Ptr 使用上的小細節,本系列假設讀者對 Smart Ptr 有一定程度的認識,只做一些重點探討。

目前 smart pointer 的現況:

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

這是一位網友的問題,原問題見http://www.ptt.cc/bbs/C_and_CPP/M.1351841869.A.BAF.html。本部落格之前也稍微碰過這個主題,不過之前的重點在於腦筋急轉彎式的模擬 __VA_ARGS__ 功能,實用性是另一回事。

在開始討論各種作法可行性之前,這裡先宣導一項原則:應該要讓正常輸出與非常態輸出分流,更精確的說,給使用者看的輸出應該要和給開發者看的輸出分流。例如使用 stdout 作為正常輸出時,就不應該也用 stdout 作為非常態輸出,而是改用 stderr 或檔案。實戰中非常態輸出的 sink 很多樣,這裡就不多說了。即使不想多花心力去設計非常態輸出機制,使用基本的 stderr 並不會比用 stdout 多費功夫,好處卻是立即可見,可謂有利而無害。

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

最近看到有人出了一個考初學者的問題,於是我改了一個複雜化的版本,應該蠻適合拿來鑑別初學者的程度。假設使用的語言為 C++,下面這個 expression 有幾種可能性?

   (f(a) && f(b))

任何一個有把教科書第一章念完的人差不多都會回答,執行順序類似於:

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

這個實驗在電腦裡躺了一段時間了,雖然不是很有價值的實驗,但想說既然做了不如就整理一下放上來吧。

大約兩個月前在 xkcd 上看到有位仁兄挑戰既有的資料結構常識「假使只查詢而不需要更新資料,使用排序陣列搭配二分搜尋,效能通常會勝過複雜精巧的二元搜尋樹」。這位仁兄很意外的發現,用 std::lower_bound 對排序過的 vector 做二分搜尋比 map 還慢。他提供的程式很快被網友點出兩個錯誤:

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

算是回答一個網友的問題。(真希望回答問題有錢可拿.....)

在沒有標準程式庫的情況下,計算 sin、cos 這些函數值最直覺的方法可能是用級數逼近。但假如我們只想求有限範圍內離散數字的三角函數值,級數逼近就顯得有點複雜了。

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

這是一位網友出的問題:要如何偵測某個型別是否可以套用大於運算式( > expression )呢?這裡假設是在 C++ 03 的標準之下。

熟悉 C++ 的網友應該都會想到可以靠 SFINAE 手法解決這類偵測問題。仿照 tr1 type_traits 的使用風格,典型的寫法大概像這樣:

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

每隔一段時間就會看到有人對機器語言、組合語言感興趣,特別是剛翻了幾本書的初學者,但很多人只對書上幾句描述有點含糊的理解而已。這也未必不好,個人的能力是有限的,應該把精力放在對自己最有價值的事物上。只是有時候看到有初學者指明要學「機器語言」,不免讓人覺得好笑。

如果你真的對機器語言長什麼樣子很感興趣,而且很碰巧使用 x86-32 處理器就繼續往下看吧。以下假設讀者已經對 x86 組合語言有基本的認識。

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

我幫 Code Express 開了一個 Google code 專案,大家可以去下載來用用看。

功能上和前一版有些許不同,但我現在暫時沒有時間寫說明檔。我想詳細的文字敘述可能沒幾個人有耐心看,不如直接看影片示範吧:

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

如果網友常用 Notepad++ 寫程式而且又需要 Snippet 功能,進來這裡就對了。花個五分鐘時間,我介紹一下 Code Express 這個 plugin。

Notepad++ 已經有很多 plugin 了,雖然 Snippet 功能也不少,但我用起來總是不太順手。之前比較有人用的 QuickText 雖然操作簡單,但它改變 Notepad++ 的行為到了難以使用的地步,若是只為了 Snippet 功能實在得不償失。另外兩個非常優秀的實作是 FingerText 和 Zen Coding,其中 Zen Coding 專注在 WEB 開發上,和我平常的應用比較無關;FingerText 和 QuickText 一樣完全採用 Tab 鍵 觸發的方式,使用起來非常方便,並且採用特殊文字標記的方式完全避開 QuickText 的 bug。

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

1 23