在初始化全局变量时使用 assert 宏
Using the assert macro while global variables are initialized
在下面的代码中,第一个 assert
不会编译,因为至少在 MSVC2015RC 中,它基本上定义为 assert(expression) (void)(!!(expression))
.
int x = 1;
assert( x == 1 );
void foo()
{
assert( x == 1 );
}
错误信息是
C2062 type 'void' unexpected
第二个断言编译没有问题,但它不会执行,除非调用 foo()
。我想在初始化全局变量时使用 assert
。有什么解决方法吗?
这里有两个问题。
首先,只有声明(例如变量、class、函数)可以进入全局范围。 assert()
不是声明,这就是为什么你不能在那里做。
这可能会导致一种变通方法,将其推入声明中,例如:
int x = 1;
namespace assert_x_is_1 {
bool _ = (assert(x == 1), true);
}
在 gcc 上,上面的代码编译得很好,如果 x
不是 1,就会断言。但是,在 clang 上,这会导致第二个问题:assert()
真的想在函数中使用- 它使用仅在函数中定义的宏。
因此,您可以拼凑一个 class 声明:
#define ASSERT_CLASS2(expr, ctr) namespace assert##ctr { struct Asserter { Asserter() { assert(expr); } } s; }
#define ASSERT_CLASS(expr) ASSERT_CLASS2(expr, __COUNTER__)
int x = 1;
ASSERT_CLASS(x == 1);
这将在半匿名命名空间中创建一个全局变量,该变量将在其构造函数中声明表达式。这适用于 clang 和 gcc。
在c/c++中,语句如
x==1
不能写超出功能
assert( x == 1 );
预编译时会被替换
(void)(!!(x==1));
是语句,不能写在函数定义之外
在下面的代码中,第一个 assert
不会编译,因为至少在 MSVC2015RC 中,它基本上定义为 assert(expression) (void)(!!(expression))
.
int x = 1;
assert( x == 1 );
void foo()
{
assert( x == 1 );
}
错误信息是
C2062 type 'void' unexpected
第二个断言编译没有问题,但它不会执行,除非调用 foo()
。我想在初始化全局变量时使用 assert
。有什么解决方法吗?
这里有两个问题。
首先,只有声明(例如变量、class、函数)可以进入全局范围。 assert()
不是声明,这就是为什么你不能在那里做。
这可能会导致一种变通方法,将其推入声明中,例如:
int x = 1;
namespace assert_x_is_1 {
bool _ = (assert(x == 1), true);
}
在 gcc 上,上面的代码编译得很好,如果 x
不是 1,就会断言。但是,在 clang 上,这会导致第二个问题:assert()
真的想在函数中使用- 它使用仅在函数中定义的宏。
因此,您可以拼凑一个 class 声明:
#define ASSERT_CLASS2(expr, ctr) namespace assert##ctr { struct Asserter { Asserter() { assert(expr); } } s; }
#define ASSERT_CLASS(expr) ASSERT_CLASS2(expr, __COUNTER__)
int x = 1;
ASSERT_CLASS(x == 1);
这将在半匿名命名空间中创建一个全局变量,该变量将在其构造函数中声明表达式。这适用于 clang 和 gcc。
在c/c++中,语句如
x==1
不能写超出功能
assert( x == 1 );
预编译时会被替换
(void)(!!(x==1));
是语句,不能写在函数定义之外