Is there a way to identify all the unused global variable in a C project?

女生的网名这么多〃 提交于 2019-12-19 17:42:07

问题


I'm cleaning up some C code. There are global variables everywhere, but not all of them are used. I want to clean up those. But it's too much work to test them one by one. Is there are easy way to do that?


回答1:


You can generate a list of all global variables in your directory using the very helpful ctags(1) command with the -x command line option:

ctags  -x  --c-kinds=v  --file-scope=no *.c

This can be combined with the also-helpful gid(1) command (assuming you've run mkid(1) on your sources first):

for name in `ctags  -x  --c-kinds=v  --file-scope=no *.c | awk '{print $1;}' | sort -u` ; do gid -R filenames $name ; done

This gives you a helpful list of which files use which globals:

$ for name in `ctags  -x  --c-kinds=v  --file-scope=no *.c | awk '{print $1;}' | sort -u` ; do gid -R filenames $name ; done
basedir        parser.h ./{parser_include,parser_main}.c
binary_input   parser_main.c
cache_fd       parser.h ./{parser_interface,parser_main}.c
conf_quiet     parser.h parser_main.c
conf_verbose   parser.h ./{parser_interface,parser_main}.c
...

It isn't perfect (as Ira points out), but it should be a good start.




回答2:


If they are only used within the file, you can declare them "static" and GCC will warn if they are never used.

If they are used from multiple files... I'm not sure how you could detect that, other than grepping or using an IDE, because they will show up as linker symbols and could in theory be accessed by any code that links with your code...




回答3:


This answer applies to the original question. The question has subsequently been changed.

It is impossible in principle to determine if a global variable is used or needed. Constructors can have side-effects, so even if a global is never accessed, it may still be needed.

True story: Programmer who shall remain nameless removed an 'unused' global from a production application. Unfortunately, the constructor for that global allocated memory from an allocator that initializes on first allocation.

As a result of him removing the unused global, the next object created using that allocator caused the allocator to initialize. Unfortunately, the initialization wasn't thread-safe (and was clearly documented as such) -- the purpose of the global was to ensure it initialized before any threads were created.

Let's just say there were very bad consequences (involving this company's largest customer -- a well-known three-letter government agency) and leave it at that.

A human being must make the determination that a global does not need to be created just because it is unused, and that can be a remarkably complicated decision to make.




回答4:


Easy? No. For a global variable X, you need to scan every compilation unit in your code for a potential access to X (a read, a write, or the generation of a reference). If there are no such accesses, then you can be reasonably sure (you don't have any assembly code, right?) that X isn't used.

It may even be the case that X is referenced in one of the above ways, but in fact has no actual effect on the program (e.g., X is read but ignore, written but not read, address taken but never dereferenced). That makes X effectively dead. Determining this requires global data flow analysis.




回答5:


(@ChrisLutz posted this idea as a comment, but I thought of it before I read the comment so I'm going to post it anyway. I'll try to add some value by expanding on it.)

In a separate copy of your source code, comment out the declarations of all your global variables and recompile everything. Compare the list of variables you commented out to the ones mentioned in compiler error messages. Anything not mentioned in an error message is unused.

Note that your build process might not try to build everything of some compilations fail, so that could give you some incomplete results.

A slightly different approach that avoids this problem is an iterative one: comment out all your globals, try to build, then uncomment the declarations for anything that the compiler complained about. Iterate until you get a clean build, and see what's still commented out.




回答6:


Doxygen may be able to give you a list of uses for global variables.



来源:https://stackoverflow.com/questions/7949274/is-there-a-way-to-identify-all-the-unused-global-variable-in-a-c-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!