C 格式化異常訊息字串的小技巧

2021-09-19 01:31:29 字數 1652 閱讀 3940

相比其他語言,c++的異常是比較primitive的,沒有語言層面的stack-trace, stl裡的異常類也很有限. 然而作為modern c++,異常還是必不可少的,雖然有很多人主張pure error code based error handling, 但是這樣會介入control-flow, 也使**更加複雜. 然而異常的乙個不足在於它的constructor的引數是乙個字串而已,很多時候我們希望在異常丟擲的時候提供一些context information,比如變數的值等等. 最近看facebook的folly c++ 庫得到一點啟發,所以動手寫了一些utility template functions 來包裝異常丟擲,同時提供格式化的異常資訊。具體**如下

templatevoid throw(targs&&... rest) 

templatevoid throwonfalse(tval&& value, trest&&... rest)

} // enable exception with formatted string message

templatevoid throwf(const char* fmt, ...)

乙個macro就搞定了,如下

#define throw_fmt(exception, fmt, ...) \

throwf("[error] %s:%d:%s:\n" fmt "\n", __file__, __line__, __func__, ##__va_args__ )

#define check_throw(cond,e) \

if(!(cond)) \

throwf("[checkfailure] %s:%d:%s:\n" "failed condition: " #cond , __file__,__line__,__func__ )

另外,定義custom exception也是乙個很枯燥的事情,很多時候就是繼承std::exception或者std::runtime_error所以寫了乙個macro來簡化自定義異常類的構造

#define new_rt_exception(e) class e: public std::runtime_error\

\explicit e(const std::string& m): runtime_error(m){}\

virtual ~e(){}\

}

在之前的**中,注意到tostr()函式,實際上是乙個模板函式,用來做 convert everything to string,是乙個受folly啟發寫的乙個簡化版本. 其實就是很多函式特化而已,部分**如下

/// /// everything conversion to string

///

template std::string tostr(tsrc src)

template<>

inline

std::string tostr(double src)

// variadic template version

templatestd::string tostr(tsrc src, trest&&... rest)

格式化字串小實驗

在 裡看到格式化字串攻擊的說明,不是很理解,決定實踐一下,結合tim newsham的format string attacks 進行實驗。這裡只測試了一下 x和 n引數,更多種類的格式化字串攻擊請查閱其他資料。至於測試的環境,應當是c編譯環境都可以,但是在實驗過程中,我發現dev c 預設不對 n...

C 字串格式化

c 字串格式化 1 格式化識別符號 標準的數學格式字串用於返回通常使用的字串。它們通常象x0這樣的格式。x是格式化識別符號,0是精度識別符號。格式識別符號號共有9種,它們代表了大多數常用的數字格式。就像下表所示 字母含義 c或ccurrency 貨幣格式 d或ddecimal 十進位制格式 十進位制...

C 格式化字串

在c 程式開發中,我們會經常需要獲得某種格式化的字串,比如 顏色值 ff00ff,貨幣 2.00,日期2012 03 14等等。在c 中格式化字串,一般會用到string.format 和.tostring 兩個函式。1.已知顏色的rgb值,獲取顏色的字串格式 ff00ff。ff0ff string...