我有以下宏用于某些编译时检查:
/* in-expression compile-time check evaluating to 0 */
#ifdef __cplusplus
template<bool> struct Chk_sa;
template<> struct Chk_sa<true>{};
#define Chk(test) (sizeof((Chk_sa<!!(0+(test))>())) * 0)
#else
#define Chk(test) (sizeof(struct { int (Chk):((0+(test)) ? 1 : -1); }) * 0)
#endif
/* ensure value x is a constant expression */
#ifdef __cplusplus
template<bool,bool> struct CEx_sa;
template<> struct CEx_sa<true,false>{};
template<> struct CEx_sa<false,true>{};
#define CEx(x) (sizeof((CEx_sa<!!(0+(x)), !(0+(x))>())) * 0 + (x))
#else
#define CEx(x) (sizeof(struct { int (CEx):(((0+(x)) && 1) + 1); }) * 0 + (x))
#endif
/* usage like this: */
struct ChkTest {
int expr1[Chk(3*3) + 1]; // supposed to be [1]
int expr2 : CEx(3*3); // supposed to be : 9
};
但是,此部分的 C++ 部分失败,并在
Chk
部分之前的 )
处使用 * 0
宏时出现解析错误。 (为了完整性,我包含了 CEx
部分,因为我需要修复这两个部分。)
如何更改这些以适用于较旧的 G++ (GCC) 版本?具体来说,这些在 Debian etch (G++ 4.1.1) 上工作,但在 Debian sargs (G++ 3.3.5) 及更早版本上失败。
(注:我是一名 C 程序员,但不太了解 C++。)
更新:已请求准确的错误消息。我将上面的代码片段保存到文件中
x
:
$ gcc -x c -c x
$ gcc -x c++ -c x
x:22: error: parse error before `)' token
x:23: error: parse error before `)' token
我设法弄清楚了:
template<bool> struct mbccChkExpr_sa;
-template<> struct mbccChkExpr_sa<true>{};
-#define mbccChkExpr(test) (sizeof((mbccChkExpr_sa<!!(0+(test))>())) * 0)
+template<> struct mbccChkExpr_sa<true> { typedef int Type; };
+#define mbccChkExpr(test) (static_cast<mbccChkExpr_sa<!!(0+(test))>::Type>(0))
和:
template<bool,bool> struct mbccCEX_sa;
-template<> struct mbccCEX_sa<true,false>{};
-template<> struct mbccCEX_sa<false,true>{};
-#define mbccCEX(x) (sizeof((mbccCEX_sa<!!(0+(x)), !(0+(x))>())) * 0 + (x))
+template<> struct mbccCEX_sa<true,false> { typedef int Type; };
+template<> struct mbccCEX_sa<false,true> { typedef int Type; };
+#define mbccCEX(x) (static_cast<mbccCEX_sa<!!(0+(x)), !(0+(x))>::Type>(0) + (x))
我仍然想知道是否可以以某种方式将
x
的类型放入后者中,这样我就可以做 static_cast<…>(x)
而不是 static_cast<…>(0) + (x)
但这已经可以工作了,在 OpenWatcom 和 sarge 的 g++
上也是如此。