如何确保不使用变量

How to make sure that a variable is not used

提问人:tommsch 提问时间:5/17/2021 更新时间:5/18/2021 访问量:474

问:

问题

我有一个函数需要一些参数,我怎样才能确保该变量不在正文内部使用,在最好的情况下通过编译错误?例如,以下内容不应编译faa

void f( int & a ) {
    UNUSED( a );  // some magic rendering the variable a unusable
    ++a;
}

问题的故事:

在我的一些函数中,一些变量在发布模式下编译时未使用,而在调试模式下使用。因此,为了压制警告,我把自己变成了一个宏。但后来,我意识到宏的正确名称应该是 .UNUSED( varname )MAYBE_UNUSED( varname )

使用案例UNUSED()

我有一组(难以计算)函数的实现。所有实现都应具有相同的签名,因此可以很容易地相互替换。但某些实现不得使用某些输入参数。要明确这一点(对于读者和编译者来说),这种魔力将是有用的。UNUSED

C++

评论

5赞 ChrisMM 5/17/2021
void f( int & /* a */ )?
0赞 paladin 5/18/2021
只需使用函数重载即可。

答:

4赞 Jorengarenar 5/17/2021 #1

C++ 允许您使用未命名的函数参数。对于您不打算使用相应参数但必须声明它以匹配签名的情况,例如在将回调写入某个库时,它非常有用。

只需重新定义您的函数:

void f(int&) {
    // code ...
}
1赞 mediocrevegetable1 5/18/2021 #2

虽然@Jorengarenar的答案可能是你想要的,但这个想法仍然让我感兴趣。这是我能做的最接近的。它利用了这样一个事实,即作用域中的变量会隐藏具有相同名称的外部作用域中的变量。所以这里是:

#define UNUSED(var_name) \
    class UnusedClass_ {} var_name

井。。。这很简单,不是吗?但是,这是在实际函数中使用它的示例,您会看到强加给您的轻微烦恼:

#define UNUSED(var_name) \
    class UnusedClass_ {} var_name

void f(int &a)
{{
    UNUSED(a);
    ++a; // error: no match for 'operator++' (operand type is 'f(int&)::UnusedClass_')
}}

注意到额外的牙套了吗?你看,必须有另一个作用域,我们在其中创建一个类型的新对象。每当我们提到现在时,它都会遮蔽 .我们不能省略大括号;如果我们这样做,我们将收到一个错误,用于重新定义。现在的实际工作方式是它只是一个空类,所以没有运算符会处理它,而且你可能不能把它放在任何函数参数中(除非它可能是一些模板函数,对其参数不做任何事情)。在大多数情况下,这应该会给出错误。 不会,而且可能有一些方法可以让你不遗余力地让这个类/宏做一些它不应该做的事情。UnusedClass_aUnusedClass_aint &aaUnusedClass_a;

您还可以放置一个仅包含变量名称的空语句,以断言该变量确实存在:

#define UNUSED(var_name) \
    (void) var_name;     \
    class UnusedClass_ {} var_name

void f(int &a)
{{
    UNUSED(b); // error: 'b' was not declared in this scope
}}

这是最好的解决方案吗?可能不是,像其他答案中那样省略函数名称可能是一个更好的主意。这只是一种概念验证,可能不应该在现实生活中使用,因为可能还有其他选择。

评论

0赞 Pete Becker 5/18/2021
包含两个连续下划线 () 的名称和以下划线后跟大写字母开头的名称将保留供实现使用。不要在代码中定义它们。UnusedClass__
0赞 mediocrevegetable1 5/18/2021
@PeteBecker正是出于这个原因,我避免了前缀下划线,但我没有意识到造成了同样的问题。将其减少到 1 个下划线,谢谢:)__
1赞 Pete Becker 5/18/2021
是的;“包含”让很多人感到惊讶。在过去,cfront(将 C++ 代码编译为 C 代码)生成具有多个连续下划线的名称。此规则可防止 C++ 代码无意中创建与生成的 C 代码中的名称冲突的标识符。如今,库实现者依靠它来保护他们的代码免受鲁莽用户的掠夺。<克>