How to find irrelevant unused attributes?

1.1k views Asked by At

While reading parts of the code of a big C project, I found some arguments that were marked as unused but were in fact used in the function.

I thought about grepping the unused attributes but there are too many of them to manually verify if they are really unused.

My question is the following: is there a way to ask to gcc (or clang) if any attributes are not justified or not applied? Basically, for that kind of code:

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

I would like a warning telling my that my argument is not unused.

4

There are 4 answers

0
Bo M. Petersen On BEST ANSWER

I can't really take credit for this, as I stumbled upon it at http://sourcefrog.net/weblog/software/languages/C/unused.html. It causes UNUSED variables to give compiler errors when you attempt to use them.

#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

It wont help you find unused variables, but once found you can ensure they really are unused.

7
alk On

You can #define the unused away, like so

#define unused

Empty __attribute__ statements are ignore and the compiler shall issues a warning about "unused parameter, if ran with the right option (-Wunused-parameter) enabling warnings.

However this could break the code if the character sequence unused is used somewhere else in the code, as it would disappear there also.

0
Maxime Chéramy On

I used alk answer but I'm giving more details for those facing the same problem.

First part:

alk suggested to define a macro named unused. Since it's a large project with several build units and Makefiles, I decided to define the macro using gcc:

gcc -Dunused= ...

Then, I've cleaned-up the project and rebuilt:

make clean && make

That went very badly because of variables called unused_something in the code. So I had to rename these variables in order to continue.

Since I'm using the -Wall option, I'm now getting a lot of warnings that all look like:

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)
                                                                 ^

So I reran with:

make clean && make > out 2>&1

And now, I grep the result:

grep Wunused-parameter out

I'm getting all the warnings with the name of the file and the line number.

Second part:

Since I use git, I can directly do:

git grep -n "((unused))"

With that, I have all the lines containing the attribute unused. However, if a line contains two or more unused attribute, I'll get it only once.

Last part:

I check which lines are not on both outputs, manually :/.

0
danyowdee On

I cannot speak for GCC, but you can teach Clang to scream and shout using the -Werror-used-but-marked-unused flag.
You can cover the opposite case too using -W(error-)unused-parameter.

Because there are so many useful warnings in Clang, I usually just use -Werror -Weverything, though—selectively ignoring the ones I’m not interested in, and preventing e.g. implementing/calling deprecated functions/methods to be promoted to errors using -Wno-error-....