其他分享
首页 > 其他分享> > c-具有几行参数的宏功能?

c-具有几行参数的宏功能?

作者:互联网

在C中
我需要定义一个宏.
该宏将参数“块”作为参数.

我们可以安全地使用几行代码作为宏函数的参数吗?

我问自己是否:

>以下代码是否有效,并由标准定义为有效,例如“跨平台”?
>有没有更好的方法可以做到这一点(我不能在这里使用模板函数,因为我需要上下文).

#define MY_MACRO( expr ) DOSOMETHING( (expr) ); DOANOTHERTHING( (expr) ); // etc...

int my_function() {
    int o = RandomNumber();
    MY_MACRO( 
        int k = AFunction();
        k++;
        AnotherFunction( k + o ); // here I need to keep the context of the call
    ); 
}

我们不能使用函子,因为我们需要访问调用的上下文.
我们不能使用lambda(snif),因为我们使用的是不提供lambda的旧编译器(并且我们无法更改它).

解决方法:

16.3 / 9:

Within the sequence of preprocessing
tokens making up an invocation of a
function-like macro, new-line is
considered a normal white-space
character.

因此,通常多行宏调用是可以的.当然,如果DOSOMETHING和DOANOTHERTHING没有为范围引入括号,那么您的特定示例将重新定义k.

编辑:

We can’t use functors because we need
to have access to the context of the
call. We can’t use lambda (snif) because we use an old compiler

通常的方法是捕获函子中所需的任何变量,就像lambda一样. Lambda所做的唯一事情是函子无法“捕获所有内容”而不必将其键入,但是编写Lambda的人可以看到它们使用了哪些变量,因此只是方便,如果它们可以将它们全部键入必须.在您的示例中:

struct MyFunctor {
    int o;
    MyFunctor(int o) : o(o) {}
    void operator()() const {  // probably not void in practice
        int k = AFunction();
        k++;
        AnotherFunction( k + o );
    }
};

template<typename F>
void DoThings(const F &f) {
    DOSOMETHING(f());
    DOANOTHERTHING(f());
}

int my_function() {
    int o = RandomNumber();
    DoBothThings(MyFunctor(o));
}

您还可以通过引用捕获变量(通常使用指针作为数据成员而不是引用,以便可以对函子进行复制分配).

如果使用“上下文”,例如,您的意思是宏参数和/或宏主体可能包含break或goto,因此需要位于调用方的词法范围内,则您不能使用函子或lambda .耻辱

标签:c,macros
来源: https://codeday.me/bug/20191010/1886683.html