Category Archives: Tips

MSVC debug build

在VC++的設定: C/C++若有定義_DEBUG 則需注意link應該link MTd or MDd 因為有些function 如_free_dbg是在定義_DEBUG時會被編譯(參考<crtdbg.h>) 此時如果link到release版的MT or MD,則會出現unresolved link 另外,這個錯誤訊息也是因為_DEBUG混用造成的 error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘0’ doesn’t match value ‘2’ in … 在<yvals.h≶(一些c++ std header會間接引用) #ifdef _DEBUG #define _HAS_ITERATOR_DEBUGGING 1 #else #define _HAS_ITERATOR_DEBUGGING 0 #endif … Continue reading

Posted in Tips | Leave a comment

exception assert使用時機

exception和assert是完全不同的東西, assert是用來確認條件與狀態的一致性的方法(用在確定該條件為真,如果不成立,則代表程式有bug),而exception是將錯誤傳遞出去(發生在隱藏錯誤與傳遞錯誤的內外邊界)。 舉例來說 在一些語言裡存取null pointer的方法時會因發exception,假如可以確定不可能是null pointer,則應使用assert來檢查是否有不預期的狀態出現,因為當exception發生時,常常會被外層try catch接住而將問題(bug)屏蔽。導致當系統出現不預期行為時,已經和發生點找不到直接的關聯 另外在switch case中enum變數的值通常會是特定的值,如果在switch block中有default,當問題發生時很可能enum變數的值是invalid直接落入default action而未發現問題,這時候用assert檢查enum值的區間就有意義,這種情況常發生在物件已經是invalid(或指到錯誤的位置) 這些bug常見於multithread的程式開發中,特別是debug相當困難,結果常是莫名的segmentation fault crash,而利用assert來檢查物件的狀態變數是否符合預期,物件的member variable是否落在valid的區間,早期發現問題。 exception常是用在邊界上的錯誤傳遞(邊界的定義不是絕對的,要看context而定,可能細至api被呼叫者與呼叫者的邊界) assertion可以想成在系統邊界內的所有程式碼,都安全地假設狀態和值都是符合預期 至於assertion要assert什麼? 可以參考programming by contract(C.A.R. Hoare.)這樣的概念 Pre-conditions, Post-conditions, Invariants 對於使用者輸入的邊界檢查很顯然是利用exception而非assert,因為超出邊界並不是bug, 除非是經過一系列檢查後進入系統邊界內,這時候使用assert檢查就合理了 狀態跑掉常見的原因是multithread程式中lock出現問題,從而導致race condition, 另外如果物件被提早釋放掉,object內的function存取部分member variables出現不預期的值, 通常這類情況不會馬上出問題,但很容易在後面出現heap corruption,此時卻不知道是從哪裡造成的。 特別是如果大量使用asynchronous API,更難追蹤來源,並且asynchronous API的callback有可能是不同thread呼叫。 透過使用debugger可以追蹤當下發生中斷的stack frames,但需配合assert,縮小問題可能的發生點。 參考連結: https://www.edn.com/electronics-blogs/embedded-basics/4440193/8-tips-for-squashing-bugs-using-ASSERT-in-C … Continue reading

Posted in Tips | Leave a comment

library使用注意macro define

在使用第三方函式庫時,要注意build library和use library(shared, static)的macro選項 例如: CURL_STATICLIB 或是header only選項 cppnetlib BOOST_NETWORK_NO_LIB 另外是注意編譯時的macro define,有可能使用時須要一致。 以後有注意到再繼續補

Posted in Tips | Leave a comment

gcc turn off exceptions:-fno-exceptions

在g++編譯時,程式若為了效能考量可能希望減少執行時對exception機制的overhead,可用-fno-exceptions 這個選項關掉exception 但此時就無法使用try catch 可用 #if __cpp_exceptions 來做處理, 或是使用c processor的predefined macro https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html __EXCEPTIONS This macro is defined, with value 1, when compiling a C++ source file with exceptions enabled. If -fno-exceptions is used when compiling the file, then this macro … Continue reading

Posted in Tips | Leave a comment

VS2015 – copy header files

use post build event 利用帶入巨集變數$(SolutionDir),在powershell script讀取SolutionDir powershell -ExecutionPolicy Unrestricted $(SolutionDir)\copyheader.ps1 -SolutionDir $(SolutionDir) copyheader.ps1 param([string]$SolutionDir); $src1 = $SolutionDir + “Http” $dest1 = $SolutionDir + “output\http” Copy-Item -Path $src1 -Filter “*.h” -Recurse -Destination $dest1 -Container -force -force 強制overwrite 這樣會recursive的複製.h檔到對應的目錄 試過xcopy bat,比較起來powershell script處理方式較簡潔

Posted in Tips | Leave a comment

wait on thread creation

下面的範例是一般worker thread的做法,利用boost threadgroup,在程式一開始由一個thread進入(main thread),離開的時候也是一個thread 一般來說在創建thread時不需要等待thread被創建完成再往下走,不過這裡示範了當所有thread建立完成後main thread才繼續往下執行(透過condition variable, wait) 這麼做可以讓控制流變的簡潔,並且視thread group的threads為一整體,也能確保在start()完成之前不會執行stop()。 ThreadManager.h #include #include #include #include #include class ThreadManager { std::mutex m; std::condition_variable cv; int numThreads = 5; //non-static data member with initializer (C++11) int startCount = 0; bool bRunning = … Continue reading

Posted in Tips | Leave a comment

warning C4819的處理

warning C4819: The file contains a character that cannot be represented in the current code page (950). Save the file in Unicode format to prevent data loss 選擇 File>Advanced Save Options => Encoding: Unicode (UTF-8 with signature) – Codepage 65001 … Continue reading

Posted in Tips | Leave a comment

VC++ pragma link

在VC++中 #pragma comment(lib, “my.lib”) 在link階段會搜尋 my.lib 一般配合_DEBUG與_MSC_VER 等巨集使用 可以根據編譯的特性來動態決定要link哪一個lib 例如 #if _MSC_VER >= 1400 #pragma comment(lib, “my.lib”) #elif … #endif 使用時建議放在單獨的cpp檔方便查找 MSVC++ 15.0 _MSC_VER == 1910 (Visual Studio 2017) MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) MSVC++ 12.0 _MSC_VER … Continue reading

Posted in Tips | Leave a comment

C/C++ comments

註解主要的目的是讓其他人可以快速的理解程式碼,或是原始作者在後來修改自己的程式碼,不至於深陷混亂的程式碼泥沼當中。但必須要注意註解過多過冗長不宜,因為註解本身不能取代程式碼,而程式碼才是主體。所以在註解上基本的原則是: 要說明function/class的目的,在function內部不易閱讀的地方註記使用的演算法或是方法的目的(rationale),讓閱讀者可以抓住開發者當時的思路。 workaround的部分也必須註記,因為通常workaround不是在原來的正常思路當中,如果不加以註記,有很大的機會在後來會完全摸不著頭緒 另外是如果整合了文件產生工具或是IDE整合,為了要讓工具提取重要的metadata,註解的格式就會有所規範,可以參考https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,XML Documentation (Visual C++) 在C/C++裡註解分兩種: 單行註解(single-line comments, C style) 與 多行註解(multi-line comments, C++ style)C89不支援單行註解,但C99標準加上了 將整段程式碼註解時一般可用多行註解的方式,但是多行註解不可nested,故若碰到段落內已有多行註解時則要改用全部單行或是用preprocessor裡的#if 0的方式處理,或是語言本身的 if(0)。 comment style有時候為了使註解醒目,會用一些排列方式呈現 一般來說,程式原始檔的註解會標記 檔案 作者 變更紀錄function, class 等的註解 相關參考資料:https://google.github.io/styleguide/cppguide.html#Commentshttp://en.cppreference.com/w/c/commenthttp://en.cppreference.com/w/cpp/commenthttp://www.oracle.com/technetwork/java/javase/documentation/index-137868.htmlalsoISO/IEC 9899:1999 6.4.9ISO/IEC 9899:1990 6.1.9

Posted in Tips | Leave a comment