在初始化全局变量时使用断言宏
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 类型"空"意外
第二个断言编译没有问题,但除非调用foo()
否则不会执行。我想在初始化全局变量时使用assert
。有什么解决方法吗?
这里有两个问题。
首先,只有声明(例如变量、类、函数)可以进入全局范围。 assert()
不是宣言,这就是为什么你不能在那里做。
这可能会导致一种解决方法,只需将其推入声明中,例如:
int x = 1;
namespace assert_x_is_1 {
bool _ = (assert(x == 1), true);
}
在 gcc 上,上面的编译很好,如果 x
不是 1,就会断言。然而,在 clang 上,这导致了第二个问题:assert()
真的想在函数中使用 - 它使用仅在函数中定义的宏。
因此,为此,您可以编写一个类声明:
#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));
这是一个语句,不能写在函数定义之外
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 如何将断言放在类初始化列表之前
- 断言错误,即使在使用 new 初始化字符指针后也是如此
- 调试断言因通过用户输入初始化类的数组而失败
- 唯一ptr初始化断言失败
- 当未初始化的内存传递给函数时,如何断言/测试
- 初始化一个常量变量,如果失败则断言(c++)
- 调试断言失败!表达式:is_block_type_valid(标头>_block_use)。对象不会初始化和推送错误
- C++结构初始化断言失败
- 在初始化全局变量时使用断言宏