旧版 G++ 的常量表达式的表达式编译时检查

问题描述 投票:0回答:1

我有以下宏用于某些编译时检查:

/* 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
c++ templates compile-time static-assert
1个回答
0
投票

我设法弄清楚了:

 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++
上也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.