c++11中未使用的参数
Unused parameter in c++11
在c++03及更早的版本中,为了禁用编译器对未使用参数的警告,我通常使用这样的代码:
#define UNUSED(expr) do { (void)(expr); } while (0)
例如
int main(int argc, char *argv[])
{
UNUSED(argc);
UNUSED(argv);
return 0;
}
但是宏不是c++的最佳实践,所以。c++11标准有没有更好的解决方案?我的意思是我能摆脱宏吗?
谢谢大家!
可以省略参数名:
int main(int, char *[])
{
return 0;
}
在main的情况下,您甚至可以完全省略参数:
int main()
{
// no return implies return 0;
}
参见c++ 11标准中的"§3.6 Start and Termination"
在 c++ 11中有<tuple>
,其中包括准备使用std::ignore
对象,这允许我们编写(很可能不会强加运行时开销):
void f(int x)
{
std::ignore = x;
}
我使用了一个空体函数:
template <typename T>
void ignore(T &&)
{ }
void f(int a, int b)
{
ignore(a);
ignore(b);
return;
}
我希望任何严肃的编译器都能优化函数调用,它会为我静音警告。
要"禁用"此警告,最好是避免写参数,只写类型。
void function( int, int )
{
}
或者,如果你喜欢,注释掉它:
void function( int /*a*/, int /*b*/ )
{
}
可以混合使用已命名参数和未命名参数:
void function( int a, int /*b*/ )
{
}
对于 c++ 17,您有[[maybe_unused]]属性说明符,如:
void function( [[maybe_unused]] int a, [[maybe_unused]] int b )
{
}
没有,没有。
所以你被困在相同的旧选项。您是否愿意完全省略参数列表中的名称?
int main(int, char**)
当然,在main
的特定情况下,您可以简单地省略参数本身:
int main()
还有一些典型的特定于实现的技巧,例如GCC的__attribute__((unused))
。
你对传统的标准方式有什么不满?
void f(int a, int b)
{
(void)a;
(void)b;
return;
}
宏可能不是理想的,但是它们在这个特定的目的上做得很好。我觉得还是用宏吧
Boost头文件<boost/core/ignore_unused.hpp>
(Boost>= 1.56)为此目的定义了函数模板boost::ignore_unused()
。
int fun(int foo, int bar)
{
boost::ignore_unused(bar);
#ifdef ENABLE_DEBUG_OUTPUT
if (foo < bar)
std::cerr << "warning! foo < bar";
#endif
return foo + 2;
}
psc++ 17有[[maybe_unused]]
属性来抑制对未使用实体的警告。
没有新的可用
对我来说最有效的是注释掉实现中的参数名。这样,您就可以摆脱警告,但仍然保留了参数是什么的一些概念(因为名称是可用的)。
您的宏(以及所有其他强制转换为void的方法)的缺点是,您可以在使用宏之后实际使用参数。这会使代码更难维护。
我真的很喜欢使用宏,因为它可以让你更好地控制当你有不同的调试构建(例如,如果你想构建与断言启用):
#if defined(ENABLE_ASSERTS)
#define MY_ASSERT(x) assert(x)
#else
#define MY_ASSERT(x)
#end
#define MY_UNUSED(x)
#if defined(ENABLE_ASSERTS)
#define MY_USED_FOR_ASSERTS(x) x
#else
#define MY_USED_FOR_ASSERTS(x) MY_UNUSED(x)
#end
,然后像这样使用
int myFunc(int myInt, float MY_USED_FOR_ASSERTS(myFloat), char MY_UNUSED(myChar))
{
MY_ASSERT(myChar < 12.0f);
return myInt;
}
对于时间关键的代码段,我有自己的实现。我一直在研究一个时间关键代码的减速,并发现这个实现消耗了大约2%的时间关键代码,我已经优化:
#define UTILITY_UNUSED(exp) (void)(exp)
#define UTILITY_UNUSED2(e0, e1) UTILITY_UNUSED(e0); UTILITY_UNUSED(e1)
#define ASSERT_EQ(v1, v2) { UTILITY_UNUSED2(v1, v2); } (void)0
时间关键代码使用ASSERT*
定义用于调试目的,但在发布中它显然已经被删除,但是…似乎这个在Visual Studio 2015 Update 3
中产生更快的代码:
#define UTILITY_UNUSED(exp) (void)(false ? (false ? ((void)(exp)) : (void)0) : (void)0)
#define UTILITY_UNUSED2(e0, e1) (void)(false ? (false ? ((void)(e0), (void)(e1)) : (void)0) : (void)0)
原因在双false ?
表达式中。它以某种方式在最大优化的情况下产生更快的代码。
我不知道为什么这样更快(似乎是编译器优化中的一个bug),但它至少是这种情况下代码的更好解决方案。
注意:这里最重要的是,如果没有上面的断言或未使用的宏,时间关键型代码会减慢的速度。换句话说,双false ?
表达式出人意料地有助于优化代码。
windows.h定义UNREFERENCED_PARAMETER:
#define UNREFERENCED_PARAMETER(P) {(P) = (P);}
你可以这样写:
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv) {
UNREFERENCED_PARAMETER(argc);
puts(argv[1]);
return 0;
}
或在Windows之外:
#include <stdio.h>
#define UNREFERENCED_PARAMETER(P) {(P) = (P);}
int main(int argc, char **argv) {
UNREFERENCED_PARAMETER(argc);
puts(argv[1]);
return 0;
}
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- isPalindrome不显示输出,isPalindrome函数未使用字符串输入作为字符串参数进行测试
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- 具有未使用的模板参数的函数模板
- 参数设置但未使用
- 未使用模板类型定义的同时参数包扩展错误
- 警告:用两个参数构造函数返回对象时,表达结果未使用
- clang:警告:编译期间未使用的参数:"-stdlib=libc++"
- 命令行参数未存储(使用 boost)
- C++:错误:成员访问不完整的类型,未使用的参数[-Werror,-Wunused-parameter]
- 运算符++:引用与值返回和未使用的参数
- 在C++中,是否可以使用定义中未使用的模板参数声明模板结构?
- 如何强制MSVC链接一个未使用的静态库(相当于GC——整个归档参数)
- 调试代码并C++未使用的参数警告
- C++:未使用参数优化的力度
- 是否允许类模板的函数签名模板参数中使用未展开的参数包?(可能的VS2013错误)
- 用于未使用参数参考的单线解决方案
- 函数调用中未使用的参数的模板参数推导
- 如何标记 constexpr 函数的参数未使用?
- 即使参数未使用,创建对象时是否"locked"内存空间?