如何找到不相关的未使用属性?

Posted

技术标签:

【中文标题】如何找到不相关的未使用属性?【英文标题】:How to find irrelevant unused attributes? 【发布时间】:2013-12-05 11:01:56 【问题描述】:

在阅读大型 C 项目的部分代码时,我发现一些参数被标记为未使用但实际上在函数中使用。

我考虑过 grepping 未使用的属性,但它们太多,无法手动验证它们是否真的未使用。

我的问题如下:有没有办法询问 gcc(或 clang)是否有任何属性不合理或未应用?基本上,对于那种代码:

int f(int arg __attribute__((unused))) 
    return arg + 2;

我想要一个警告,告诉我我的论点没有被使用。

【问题讨论】:

【参考方案1】:

我真的不能把这归功于它,因为我在http://sourcefrog.net/weblog/software/languages/C/unused.html 偶然发现了它。 当您尝试使用它们时,它会导致 UNUSED 变量给出编译器错误。

#ifdef UNUSED 
    // Do notthing if UNUSED is defined
#elif defined(__GNUC__) 
// Using the gcc compiler - do the magic!
#define UNUSED(x) UNUSED_ ## x __attribute__((unused)) 
#elif defined(__LCLINT__) 
#define UNUSED(x) /*@unused@*/ x 
#else 
// unknown compiler - just remove the macro
#define UNUSED(x) x 
#endif

它不会帮助您找到未使用的变量,但一旦找到,您可以确保它们确实未被使用。

【讨论】:

【参考方案2】:

你可以#defineunused离开,像这样

#define unused

空的__attribute__ 语句将被忽略,如果使用正确的选项 (-Wunused-parameter) 启用警告,编译器将发出有关“未使用参数 的警告。

但是,如果字符序列 unused 在代码的其他地方使用,这可能会破坏代码,因为它也会在那里消失。

【讨论】:

但这不会在真正需要未使用的地方产生错误警告吗? @RedX:当然。 OP 应该得到发出警告的行与 greping unused 产生的行的区别。对于此“差异”中的行,需要删除 __attribute__((unused)) 这是一个有趣的方法。如果我理解正确,我会得到警告的数量,并且可以与未使用的属性的数量进行比较。如果不同,则留下不必要的属性。但这并不能准确地告诉我额外的属性在哪里。我是对的还是我错过了什么? @Maxime Assumming "extra" == "unnecessary" 在你的评论中:grep 给你行号不是吗? 如果我添加定义,我会得到 100 个警告。如果我 grep 并找到 110 个属性,那意味着有 10 个不必要的属性。我的问题是找到他们在哪里。如果生成了警告,我仍然需要检查每个属性。如果不是,则不需要该属性。这绝对是一个好的开始,但它并不能 100% 让我满意。【参考方案3】:

我不能代表 GCC,但您可以使用 -Werror-used-but-marked-unused 标志教 Clang 尖叫和喊叫。 您也可以使用 -W(error-)unused-parameter 覆盖相反的情况。

因为在 Clang 中有很多有用的警告,我通常只使用 -Werror -Weverything,但选择性地忽略我感兴趣的警告,并阻止例如使用-Wno-error-... 实现/调用要升级为错误的已弃用函数/方法。

【讨论】:

【参考方案4】:

我使用了 alk answer,但我会为面临相同问题的人提供更多详细信息。

第一部分:

alk 建议定义一个名为 unused 的宏。由于它是一个包含多个构建单元和 Makefile 的大型项目,我决定使用 gcc 定义宏:

gcc -Dunused= ...

然后,我清理了项目并重建了:

make clean && make

这很糟糕,因为代码中的变量名为 used_something。所以我不得不重命名这些变量才能继续。

由于我使用-Wall 选项,我现在收到很多警告,看起来都像:

char/serial.c: In function ‘serial_write’:
char/serial.c:151:69: warning: unused parameter ‘odf’ [-Wunused-parameter]
 static size_t serial_write(tty_struct_t *tty, open_file_descriptor* odf __attribute__((unused)), const unsigned char* buf, size_t count)
                                                                 ^

所以我重新运行:

make clean && make > out 2>&1

现在,我 grep 结果:

grep Wunused-参数输出

我收到了带有文件名和行号的所有警告。

第二部分:

由于我用的是git,所以可以直接做:

git grep -n "((未使用))"

这样,我所有的行都包含未使用的属性。但是,如果一行包含两个或更多未使用的属性,我只会得到一次。

最后部分:

我手动检查哪些行不在两个输出上:/。

【讨论】:

以上是关于如何找到不相关的未使用属性?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node.js、Mongoose 和 Discord.js 的未定义错误 [无法读取未定义的属性]

您如何找到单级缓存的未命中惩罚?

如何针对对象的未定义属性捕获此错误?

使用 AJAX 刷新 Rails 部分时的未定义方法

如何处理调用 API 的 Next.js 中动态路由的未找到 404?

如何找到与导航属性相关的 Id 属性或属性?