其他語言已經有yield的語意了,不過C/C++必須手動模擬。
看了Coroutines in C之後,做了一下實驗。
1 | int func() |
測試VC12、GCC和Clang之後,發現GCC要使用C99
模式編譯才會成功。
不過美增加一個狀態就得增加一個LABEL,也是蠻麻煩的一件事,後來看到一個作法更好,之前從沒想過能這樣用。
1 | int func() |
從沒想過switch/case的statement可以這樣用,開了眼界了。
其他語言已經有yield的語意了,不過C/C++必須手動模擬。
看了Coroutines in C之後,做了一下實驗。
1 | int func() |
測試VC12、GCC和Clang之後,發現GCC要使用C99
模式編譯才會成功。
不過美增加一個狀態就得增加一個LABEL,也是蠻麻煩的一件事,後來看到一個作法更好,之前從沒想過能這樣用。
1 | int func() |
從沒想過switch/case的statement可以這樣用,開了眼界了。
在C++11中,可以這樣用已經不是什麼新鮮事了。
1 | vector<int> vec; |
如果要在自己的container支援這特性的話,需滿足以下條件。
begin
、end
函數,這兩個函數必須回傳一個 Iterator 。*
、++ (prefix版)
、!=
這三個operator function。1 | #include <iostream> |
1 | #ifndef _ITERATOR_DEBUG_LEVEL |
在整理Concurrency programming資料的時候,發現這個部份被我遺漏了,寫點東西免得忘記。
libdispatch 是由蘋果開發的Concurrency framework,如今也可以在FreeBSD上使用。
從FreeBSD Wiki上找來的範例
1 | #include <dispatch/dispatch.h> |
看到那個 ^{ .... }
區塊的部份就類似於其他語言的Closure,C++11的lambda expression。
至於要編譯這段程式碼,就需要
1 | # clang -Wall -Werror -fblocks -L/usr/local/lib -I/usr/local/include -o test test.c -ldispatch |
Blocks是Clang的Extension,更多資訊可以參考Programming with C Blocks,GCC不支援,至於libdispatch需要在ports下事先安裝。編譯的時候要記得加上-fblockss
。
當然,也可以有無Blocks的版本。
1 | #include <dispatch/dispatch.h> |
編譯的時候就可以拿掉-fblocks
了
1 | # clang -Wall -Werror -I/usr/local/include -L/usr/local/lib -o test2 test2.c -ldispatch |
除了Cuncurrency之外,Closure的觀念也在很多程式語言開枝散葉了。
這個pdf有對libdispatch作個簡單的介紹。
在各語言下都有類似libdispatch這樣的Framework
雖然大部分時間都在Windows/Linux底下打轉,FreeBSD被我晾在一旁(時間不夠用Orz)
不過趁著FreeBSD 10.0 Release。
把自己的9.1-Release升級到10.0-Releae,並把過程記錄下來。
1 | # freebsd-update upgrade -r 10.0-RELEASE |
安裝完10.0之後,發現gcc不存在於,全部用clang取代掉了。
另外就是使用 pkgng 來當做新的Package manager,用法就類似於 apt 或 yum。
1 | # pkg update |
解決Concurrency中shared infomation的方法不只一總,同樣是Message-based syste,Channel不過跟Actor model不同
「Go](http://golang.org/)是最著名使用Channelmodel當做標準配備的程式語言。
看看Go網站上提供的範例
1 | // A concurrent prime sieve |
原先的ch 是 [2, 3, 4, 5, 6, ….]的Channnel
在從for-loop中拿出2之後,變成[3, 4, 5, 6, …]
再度經過Filter函數,將2的倍數濾掉之後, ch1就是[3, 5, 7, 9, ….]的Channel
之後將ch1複製到ch,重複以上的動作。
在Concurrency programming流行之後,Actor Model又重新熱門起來了。
一個Actor要做的就是以下幾件事情
1 | loop() -> |
1 | class Ping(count: int, pong: Actor) extends Actor { |
根據網路上找到的資料,把它歸類為這幾個理由
在C++中,new / delete 總共有三種用法。new跟delete的用法類似,所以就以new來示範。
詳細細節可以參考operator new和operator new, operator new[]
可以透過function overload訂製自己的new和delete動作。
operater new/delete就相對於C語言的malloc/free。因此透過operator new分配到的記憶體就該用operator delete釋放。
1 | struct Object { |
這時就會使用Object裡面的new/delete的函式了。
Placement new只是operator new的一種overload版本
1 | inline void *operator new(size_t, void *_Where) |
詳細使用可以參考C++ FAQ中的介紹。
我們可以從任何記憶體位置(在Heap或是Stack都行)進行new constructor的動作。
1 | void *pMemory = malloc(sizeof(Object)); |
Placement new的存在是有意義的,可以自由控制Memory的取得方式,可以從Stack/Heap/Memory Pool中取得記憶體,對於某些情景之下有更大的
這大概是最常見的動作,基本上就是以下兩個步驟構成
看慣了x86的Intel Syntax,對於AT&T的語法還是不習慣。
使用以下方式可以將gcc編譯出來的Code變成Intel Syntax。
1 | $ gcc test.c -S -masm=intel |
這只支援gcc,clang不行。
突然想到,順手把他記下來吧。
在C++當中,如果要自己定義++和–這兩個operator,需要不同的Function signature。
1 | class Date { |
最大的差別就在於Postfix裡面有個未使用的參數。至於為什麼要這麼設計,可以參考這裡。