2

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.

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75

4 Answers4

2

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.

alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    But wouldn't this generate false warnings for where unused really is required? – RedX Dec 05 '13 at 11:57
  • @RedX: Sure. The OP should get the difference of lines issueing a warning and the lines resulting from greping for `unused`. For the lines in this "difference" the `__attribute__((unused))` needs to be removed. – alk Dec 05 '13 at 12:13
  • That's an interesting approach. If I understand correctly, I'll get the number of warnings and I can compare to the number of unused attributes. If different, there are unnecessary attributes left. But that doesn't tell me exactly where are the extra attributes. Am I right or am I missing something? – Maxime Chéramy Dec 05 '13 at 14:32
  • @Maxime Assumming "*extra*" == "*unnecessary*" in your comment: `grep` gives you line numbers doesn't it? – alk Dec 05 '13 at 14:37
  • If I add the define, I would get let's say 100 warnings. If I grep and find 110 attributes, that'd mean that there are 10 unnecessary attributes. My problem is to find where they are. I still need to check for every attribute if a warning has been generated. If not, the attribute is not necessary. That's definitively a good start but it doesn't satisfy me at 100%. – Maxime Chéramy Dec 05 '13 at 14:53
  • @Maxime: Using `grep` with option `-n` gives you **line numbers** in addtion to the filenames. gcc also gives you filenames and line numbers. Pipe gcc's and grep's results into files, add some scripting and you're done. – alk Dec 05 '13 at 15:13
  • Yes, I understood, it's just that I need to script again because they are not in the same order. – Maxime Chéramy Dec 05 '13 at 16:04
2

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.

ololuki
  • 377
  • 1
  • 7
  • 14
Bo M. Petersen
  • 230
  • 2
  • 7
2

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-....

danyowdee
  • 4,658
  • 2
  • 20
  • 35
0

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 :/.

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75