下面是一個示例setup ...宏或模板CHECKEXPR_RETURNVAL(EXPR,VAL),它在返回VAL時檢查EXPR是否爲TRUE。如何讓C++創建一個使用編譯時檢查常量和斷言變量的表達式?
這是一個不同的地方有用的 - 就像這個高度簡化的例子:
#define ISPOW2(VAL) ((0!=VAL)&&(0==(VAL&(VAL-1))))
#define _ALIGNPOW2(VAL,ALIGN) ((VAL+(ALIGN-1))&(~(ALIGN-1)))
#define ALIGNPOW2(VAL,ALIGN) CHECKEXPR_RETURNVAL(\
ISPOW2(ALIGN) , _ALIGNPOW2(VAL,ALIGN))
所以,難的是這樣的:我想要做的,如果可能的編譯時檢查,如果該值不是在編譯時確定的常量,然後執行運行時檢查。
基本上,這個想法是儘快捕捉不好的參數;如果你可以在編譯時捕獲一個壞的參數,那比在運行時發現更好。而且,編譯時版本對於常量初始值設定項是必需的。
這裏是我的兩個(失敗)的嘗試使在多個地方單機版的工作(作爲一個常量數組的大小,作爲一個枚舉初始化,並與變量的函數)。不幸的是,它們只能在編譯時(常量初始化)或運行時才工作 - 我想找出一個適用於這兩者的版本。
// CHECKEXPR_RETURNVAL - version "A"
#define CTCHECK_EXPR(EXP)(CTCheckBool<EXP>::ExistsZeroIfTrue)
template <bool bExpression> struct CTCheckBool {};
template <> struct CTCheckBool<true> {enum{ExistsZeroIfTrue=0};};
// Note: Plus ("+") is used rather than comma operator because
// the comma operator can not be used for constant initializers
#define CHECKEXPR_RETURNVAL_A(EXP,VAL) (CTCHECK_EXPR(EXP) + (VAL))
// Test Out version "A" -- works only for Compile Time Constants
#define ALIGNPOW2_A(VAL,ALIGN) CHECKEXPR_RETURNVAL_A(\
ISPOW2(ALIGN) , _ALIGNPOW2(VAL,ALIGN))
char AlignedVar_A[ALIGNPOW2_A(2,8)];
enum { AlignedVal_A = ALIGNPOW2_A(57,16) };
int TestAlignPow2_A(int val, int align)
{return(ALIGNPOW2_A(val,align));} // Compile Error
// CHECKEXPR_RETURNVAL - version "B"
template<typename T> T CHECKEXPR_RETURNVAL_B(bool bExpr,T val)
{ ASSERT(bExpr); return(val); }
// Test Out version "B" -- works only for Runtime Computed Values
#define ALIGNPOW2_B(VAL,ALIGN) CHECKEXPR_RETURNVAL_B(\
ISPOW2(ALIGN) , _ALIGNPOW2(VAL,ALIGN))
char AlignedVar_B[ALIGNPOW2_B(2,8)]; // Compile Error
enum { AlignedVal_B = ALIGNPOW2_B(57,16) }; // Compile Error
int TestAlignPow2_B(int val, int align)
{return(ALIGNPOW2_B(val,align));}
不幸的是,兩種版本都不適用於所有三種情況。是否有一個適用於所有情況的代碼結構?
聽起來類似於http://stackoverflow.com/questions/3299834/c-compile-time-constant-檢測 – Shelwien 2010-08-03 22:19:58
@Neil:這只是我在幾分鐘內寫出的一次性測試文件中試用的東西 - 它遠不及產品代碼。這些代碼當然是非法的,而且不能運行 - 這就是爲什麼我注意到它沒有編譯的問題。我要問在所有三種情況下如何正確做到這一點。但是,我不明白如何能夠驗證(特別是在編譯時)對宏的參數是否正確是如此可怕。也許你有什麼建設性的補充關於如何實現一個ALIGNPOW2(VAL,ALIGN)宏,以合法的方式檢查ALIGN是否爲2的冪? – Adisak 2010-08-03 22:30:35
好的,您希望在返回VAL時測試EXPR是否爲「TRUE」的模板或宏(如果表達式爲「TRUE」,那麼正確?)。好的。現在,如果表達式是「FALSE」,那麼應該發生什麼?空陳述?編譯器錯誤? – SigTerm 2010-08-03 22:45:07