在剛落幕的CppCon的投影片中看到這個tTrick,順手就記下來。果然C/C++是越學越不會的語言啊。
1 | template<typename T> |
如果是VC的話記得使用__FUNCSIG__
最大的用途是幫忙Debug Template Function…
在剛落幕的CppCon的投影片中看到這個tTrick,順手就記下來。果然C/C++是越學越不會的語言啊。
1 | template<typename T> |
如果是VC的話記得使用__FUNCSIG__
最大的用途是幫忙Debug Template Function…
Transducer原先是在Clojure 1.7被提出的新觀念,由於覺得這觀念實在很有趣。看了幾篇文章之後,打算寫些東西。試著一步一步前進,加深自己印象。
Transducer
是遊 Transfrom
和 reducer
兩個字合成出來的,而
– Transform: 轉換,由 A 變成 B
– Reducer: 接受輸入和先前的狀態,產生一個新的狀態
1 | vector<int> calc(const vector<int> &vec) |
這段程式很簡單就知道他在做什麼了,不過他還是有一些圈點
例如新增
了一個條件, 不能修改原有條件。
只能寫個95%相像的程式,例如
1 | vector<int> calc2(const vector<int> &vec) |
雖然一樣能夠解決問題,不過寫久了也是會覺得枯燥乏味。
這邊就缺少了Functional programming中的composability
接著用Functional Progrmaming的觀點來看這問題
先來個C++版的Map
和Filter
吧
1 | template <template <typename...> class C, typename T, typename ...TArgs, typename Fn> |
重新構建我們的函數
1 | vector<int> calc(const vector<int> &vec) |
這下子可以用組合來看這個問題了,不過這方法的問題也顯而易見。仙不論C++中間產物的影響
1 | template <template <typename...> class C, typename T, typename ...TArgs, |
1 | auto concat = [](auto result, auto input) { |
1 | auto mapping = [](auto fn) { |
1 | auto filtering = [](auto pred) { |
1 | auto compose = [](auto f) { |
1 | vector<int> calc(const vector<int> &vec) |
1 | auto compose = [](auto f, auto g) { |
1 | vector<int> calc(const vector<int> &vec) |
– CSP and transducers in JavaScript
– Transducers From Clojure to C++
– transducers in C++ 14
怕忘記,寫下來好了。先下載GCC 4.9的Source code且解壓縮。
1 | $ cd gcc-6.1.0 |
在下configure的時候可以加參數,可以參考這裡。
在Debian體系下,利用update-alternatives
來替換掉/usr/bin的gcc symbol link
1 | $ update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/x86_64-unknown-linux-gnu-gcc-6.1.0 40 |
為了工作上的需要,試著把FFMpeg放入Browser中,雖然成功了,但是效果沒想像的好,尤其是在Mobile Browsers上。
不過這也是WebAssembly打算改善的問題,目前只有Edge跟Firefox支援Asm.js程度比較高。
在FFmpeg這項目吃盡苦頭,寫個筆記紀錄怎麼認真玩Emscripten。
我是參考audioconverter.js不過用他的Script無法使用。只好自行摸索出適合的方式。
我的目標市 FFmpeg + fdk_aac ,接下來的教學就是如何做出一個包涵這兩樣的 Javascript
這個跟一般的玩Emscripten玩法沒差太多
1 | $ git clone https://github.com/mstorsjo/fdk-aacsed -i 's/gcc/emcc/g' config.mak |
$ cd ffmpeg
$ PKG_CONFIG_PATH=/home/hm/local/lib/pkgconfig/ ./configure –disable-asm –disable-outdevs –disable-indevs –disable-filters –disable-bsfs –disable-decoders –enable-decoder=mp3,h264 –disable-demuxers –enable-demuxer=mpegts –disable-muxers –enable-muxer=mpegts –disable-protocols –enable-protocol=file –enable-libfdk-aac –disable-encoders –enable-encoder=libfdk_aac –enable-filter=aresample –disable-parsers –disable-doc –disable-stripping –disable-protocol=rtp,tcp,udp,http –disable-pthreads –disable-debug –disable-network –enable-parser=h264 –disable-filter=crop –extra-cflags=-I/home/hm/local/include
1 | 產生完config.mak之後在手動改掉 |
$ sed -i ‘s/gcc/emcc/g’ config.mak
$ sed -i ‘s/g++/emcc/g’ config.mak
$ sed -i ‘s/VALGRIND_H 1/VALGRIND_H 0/g’ config.h
$ make
1 | 如果沒意外的話彙編出**不能動**的ffmpeg,不過在意料之中,編譯過程中也會告訴你沒有找到`fdk-aac`,這都無所謂,畢竟這只是中間產物,要進行最後的動作才行。 |
$ mv ffmpeg ffmpeg.bc
$ emcc -O2 ffmpeg.bc /home/hm/local/lib/libfdk-aac.a -o ffmpeg.js
1 | 接著我們用nodejs試著執行看看 |
$ node ffmpeg.js
ffmpeg version 3.1.1 Copyright (c) 2000-2016 the FFmpeg developers
1 | 成功了,不過還是不能在網頁上用 |
$ emcc -g4 -Os –memory-init-file 0 ffmpeg.bc /home/hm/local/lib/libfdk-aac.a -o ffmpeg.js –pre-js ffmpeg_pre.js –post-js ffmpeg_post.js
```
然後將ffmpeg.js複製到audioconvert.js
中的測試網頁中,就能看到他能夠動作了
emcc的表現真的有夠怪異,如果在網頁版的編譯加上-g3
以上等級的debuger info,編出來的東西跟本部能用。
編譯的過程更是痛苦連連,效果也不如想像中的好
希望WebAssembly可以彌補這一塊
根據這篇跟這篇,C++17的最終定案即將出爐。之前喊得狒狒洋洋的module
,concept
和coroutine
沒有一個列為標準配備。相對之前喊得狒狒洋洋的大變動。還真是雷聲大雨點小。
不過還是有些實用的技術可以馬上用到,學習曲線沒那麼高..
不過這年頭每個程式語言都在新增新特性,像C語言這種實在難能可貴。不過C太低階了,開發大程式實在很麻煩。真是兩難
之前說過,C++沒有return multiple value的機制,要做出類似的小果只能這麼做。
1 | std::tuple<bool, int> getValue(); |
可以用,不過不太美觀。到了C++17有了更直觀的方法
1 | auto [retB, retInt] = getValue(); |
這樣就很像go
的語法了。更多的討論可以看Returning multiple values from functions in C++
這也是另一個我覺得很棒的點
直接看範例,為進化前
1 | status_code foo() { |
進化後,可能的情況
1 | status_code foo() { |
希望這兩點未來C語言也會加回去啊
C/C++寫久了,為了轉換心情,開發了一個玩具Website Parser。把太過複雜的網頁元素清掉,只留下Title跟必要的資訊。
採用的是Python3跟BeautifulSoup4,雖然Python的文章看了不少。不過這倒是第一次認真寫點東西(雖然也只是個玩具)
用最簡單的方式來獲取網頁,方法不是最好,但是可以用。
1 | def getHtml(url): |
1 | soup = BeautifulSoup(htmlDoc, "lxml") |
1 | for script in soup.find_all('script'): |
1 | div = soup.find("div", {"id": "full-btm"}) |
1 | div = soup.find("div", {"id": "full-btm"}) |
1 | html = soup.prettify("utf-8") |
雖然只是個玩具,不過至少對Python有多一點感覺了,寫完之後才發現Sanitize HTML with Beautiful Soup這篇早就有了,真是後知後覺好幾年。
好久沒寫些東西了,雖然這篇沒什麼實用價值。在C++這種語言要模擬FP的Closure是做得到
,不過不好用
。
這邊的Clouse跟C++的Lambda Closure不太相同。
先看正常版的C++ Code
1 | struct Counter { |
一目了然的程式,也不用解釋太多。
模擬版的FP Closure
1 | struct Counter { |
真是囉唆。 Javascript還可以輸出多個函數。如果要用C++也能作到,像這樣
1 | typedef std::function<void(void)> Func; |
用tuple
和get來抓取函數時再不怎麼漂亮,也許C++17的Structured bindings
可以改善這個問題。
– Returning multiple values from functions in C++
– Emulating C++17 Structured Bindings in C++14
1 | #include <iostream> |
有些時候,我們不想要有libstdc++.so的相依性,而只要依賴libc,如果要整個重寫原先的C++ Code花費太大。
1 | #include <iostream> |
看一下相依性
1 | $ g++ test.cpp -o test |
但是如果我們這樣坐的話,一切就會不同
1 | $ g++ test.cpp -o test -static-libstdc++ -static-libgcc |
這邊有三個選項
– -static-libstdc++
連結libstdc++.a
– -static-libgcc
連結libgcc.a,如果只有-static-libgcc
而沒有-static-libstdc++
不起作用,但是反過來不是那麼一回事。
– ‘-static’ 去存所有相依性
– How to Statically Link C and C++ Programs on Linux with gcc
以下的程式碼哪裡有問題
1 | pthread_mutex_t mutex; |
所謂的Spurious wakeup
就是被Blocking的Thread認為自己滿足條件而被喚醒,而事實上不是這麼一回事。例如
Spurious wakeups may sound strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations.
由於有Spurious wakeup
的發生,為了程式的正確性,需要為此作處理。
看上面的
1 | if (q.empty()) |
當Spurious wakeup發生時,這個條件不一定滿足,因此要把if
改成while
,
由於condition variable的signal跟mutex的unlock是獨立事件,因此兩個的順序不重要,正確性都得以保證。不過這樣子的寫法一樣會造成Spurious wakeu
的問題
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
分析如下