Phi*_*ent 212 c++ gcc warnings gcc-warning
我有一个跨平台应用程序,在我的一些函数中,并没有使用传递给函数的所有值.因此我收到GCC的警告,告诉我有未使用的变量.
编码警告的最佳编码方式是什么?
围绕这个功能的#ifdef?
#ifdef _MSC_VER
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight)
#else
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/)
#endif
{
Run Code Online (Sandbox Code Playgroud)
这太丑了,但似乎是编译器喜欢的方式.
或者我在函数末尾为变量赋值为零?(我讨厌它,因为它改变了程序流程中的某些东西以使编译器警告静音).
有正确的方法吗?
Ale*_*x B 296
你可以将它放在" (void)var;"表达式中(什么都不做),以便编译器看到它被使用.这在编译器之间是可移植的.
例如
void foo(int param1, int param2)
{
(void)param2;
bar(param1);
}
Run Code Online (Sandbox Code Playgroud)
要么,
#define UNUSED(expr) do { (void)(expr); } while (0)
...
void foo(int param1, int param2)
{
UNUSED(param2);
bar(param1);
}
Run Code Online (Sandbox Code Playgroud)
ezp*_*zpz 93
在GCC和Clang中,您可以使用__attribute__((unused))预处理器指令来实现您的目标.
例如:
int foo (__attribute__((unused)) int bar) {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
ale*_*gle 38
您当前的解决方案是最好的 - 如果您不使用它,请注释掉参数名称.这适用于所有编译器,因此您不必使用预处理器专门为GCC执行此操作.
scx*_*scx 37
C++ 17现在提供了该[[maybe_unused]]属性.
http://en.cppreference.com/w/cpp/language/attributes
非常好,标准.
小智 24
一位同事在这里向我指出了这个漂亮的小宏
为方便起见,我将在下面添加宏.
#ifdef UNUSED
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
void dcc_mon_siginfo_handler(int UNUSED(whatsig))
Run Code Online (Sandbox Code Playgroud)
Mar*_*ski 22
更简洁的方法就是注释掉变量名称:
int main(int /* argc */, char const** /* argv */) {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Sha*_*our 22
在C++ 17中,我们获得了[[maybe_unused]]属性,[dcl.attr.unused]
属性标记maybe_unused指示可能故意不使用名称或实体.它应该在每个属性列表中最多出现一次,并且不存在attribute-argument-clause....
例:
Run Code Online (Sandbox Code Playgroud)[[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) { [[maybe_unused]] bool b = thing1 && thing2; assert(b); }无论是否定义了NDEBUG,实现都不应警告b未使用. - 末端的例子]
对于以下示例:
int foo ( int bar) {
bool unused_bool ;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
clang和gcc都使用-Wall -Wextra为bar和unused_bool生成诊断(实时查看).
添加[[maybe_unused]]会使诊断静音:
int foo ([[maybe_unused]] int bar) {
[[maybe_unused]] bool unused_bool ;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看到它.
在C++ 11中,UNUSED可以使用lambda表达式(通过Ben Deane)形成宏的替代形式,捕获未使用的变量:
#define UNUSED(x) [&x]{}()
Run Code Online (Sandbox Code Playgroud)
应该优化对lambda表达式的立即调用,给出以下示例:
int foo (int bar) {
UNUSED(bar) ;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们可以在godbolt中看到呼叫被优化掉了:
foo(int):
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
Phi*_*ppe 12
无宏且可移植的方式将一个或多个参数声明为未使用:
template <typename... Args> inline void unused(Args&&...) {}
int main(int argc, char* argv[])
{
unused(argc, argv);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用预处理程序指令在大多数情况下都被认为是邪恶的.理想情况下,你想像害虫一样避免它们.请记住,让编译器理解您的代码很容易,允许其他程序员理解您的代码要困难得多.像这样的几十个案例使得以后或其他人现在很难自己阅读.
一种方法可能是将您的参数放在某种参数类中.然后,您可以仅使用变量的子集(相当于您真正分配0)或者为每个平台使用该参数类的不同特化.然而,这可能不值得,你需要分析它是否合适.
如果您可以阅读不可能的模板,您可能会在"Exceptional C++"一书中找到高级技巧.如果能够阅读你的代码的人能够将他们的技能集包含在该书中教授的疯狂内容中,那么你将拥有可以轻松阅读的漂亮代码.编译器也会很清楚你在做什么(而不是通过预处理隐藏所有内容)
首先,警告是由源文件中的变量定义而不是头文件生成的.标题可以保持原始状态,因为您可能正在使用doxygen之类的东西来生成API文档.
我将假设您在源文件中具有完全不同的实现.在这些情况下,您可以注释掉有问题的参数或只写参数.
例:
func(int a, int b)
{
b;
foo(a);
}
Run Code Online (Sandbox Code Playgroud)
这可能看起来很神秘,因此定义了像UNUSED这样的宏.MFC的做法是:
#ifdef _DEBUG
#define UNUSED(x)
#else
#define UNUSED(x) x
#endif
Run Code Online (Sandbox Code Playgroud)
像这样你看到仍然在调试版本中的警告可能会有所帮助.
我已经看到了这一点,而不是(void)param2消除警告的方式:
void foo(int param1, int param2)
{
std::ignore = param2;
bar(param1);
}
Run Code Online (Sandbox Code Playgroud)
看起来这是在 C++11 中添加的
| 归档时间: |
|
| 查看次数: |
171617 次 |
| 最近记录: |