简体   繁体   English

在初始化全局变量时使用assert宏

[英]Using the assert macro while global variables are initialized

In the following code, the first assert does not compile because, in MSVC2015RC at least, it is defined essentially as assert(expression) (void)(!!(expression)) . 在以下代码中,第一个assert不会编译,因为至少在MSVC2015RC中,它实际上定义为assert(expression) (void)(!!(expression))

int x = 1;
assert( x == 1 );
void foo()
{
    assert( x == 1 );
}

The error message is 错误消息是

C2062 type 'void' unexpected C2062类型'无效'意外

The second assert compiles without problems but it is not executed unless foo() is called. 第二个断言可以毫无问题地进行编译,但是除非调用foo()否则它不会执行。 I would like to use assert while the global variables are being initialized. 我想在初始化全局变量时使用assert Is there are any workaround? 有什么解决方法吗?

Two issues here. 这里有两个问题。

First, only declarations (eg variable, class, function) can go in global scope. 首先,只有声明(例如变量,类,函数)可以进入全局范围。 assert() is not a declaration, that's why you can't do there. assert()不是声明,这就是为什么不能在那里声明。

That might lead to a workaround to just shove it into a declaration, like: 这可能会导致一种变通方法,即将其推入声明中,例如:

int x = 1;
namespace assert_x_is_1 {
    bool _ = (assert(x == 1), true);
}

On gcc, the above compiles fine and will assert if x is not 1. However, on clang, this leads to the second problem: assert() really wants to be used in a function - it uses a macro which is only defined in a function. 在gcc上,如果x不为1,则上面的代码可以正常编译,但是会断言。但是,在clang上,这会导致第二个问题: assert()确实要在函数中使用-它使用仅在a中定义的宏。功能。

So for that, you could hack together a class declaration: 因此,您可以一起整理一个类声明:

#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);

That will create a global variable in a semi-anonymous namespace that in its constructor will assert the expression. 这将在半匿名名称空间中创建一个全局变量,该名称空间在其构造函数中将断言表达式。 This works on both clang and gcc. 这适用于clang和gcc。

in c/c++, statement such as 在c / c ++中,例如

x==1

can't be wrote beyond function 不能写超出功能范围

assert( x == 1 );

will be replaced during precompiling 将在预编译期间替换

(void)(!!(x==1));

it is a statement, can't be wrote beyond function definition 这是一条语句,不能写在函数定义之外

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM