5

-Pre-condition:

I know it has many ways to ignore this warning, but I do need fix it but NOT just add some flags for compiler to ignore it, because I can do this makefile CFLAG modification on my local, but the compile/build policy can NOT been changed due to company quality control reason. This question I just want to discus who to fix it in a good way but NOT ignore them, many thanks!

Meanwhile, not ONLY some variables are never referenced, but also it has warning:

function 'xxx' was declared but never referenced

the similar problem in head file, it has some static functions, which ONLY use in one c file but many others c files include this head file.

Furthermore, this code run on a dedicate target, which has critical memory consumption, that means I need take care of each bit both in ROM and RAM.

-------Problem shows in below-----------

I currently build some codes, which provide by vendor and it contains lots of warning, because I want to have a warning free build, therefore, I put -Werror for gcc and --diag_error=[error_ref_number] for armcc.

After above makefile modification, the most warning I currently meet is

variable 'xxx' was declared but never referenced

It caused by following coding style:

in veryBIG.h, it defined some variables like (just for example but the vendor's code has exactly the same way):

static const int a = 10;
static const int b = 20;
static const int c = 30;
...
static const int z = xx;

however, many c files include this BIG head file, but ONLY one of these c file use one of above variables, it like a.c will use variable a, b.c use variable b, etc,.

I have two ways to fix:

  1. move these kind of variables into it dedicate c file, and it means head file become useless

  2. separate head files, means I create a.h, b.h, ..., z.h, and each dedicate c file include ONLY one of above head file

However, both of these two ways have limitation for my work,

Way 1:

I'm NOT sure if vendor further update will change this head file to what or have some update values, because vendor do NOT want to fix this compile warnings, that means if I follow way 1, I will manually update these variables if it has been changed by vendor (ONLY in head file, and I must synchronize them to c file) and this way makes my further merge work become complicated

Way 2:

It also makes my further merge work become NOT easy, because I do NOT use the vendor way and I also need modify the system makefile to adapt these head files into INC PATH if they are NOT locate in same folder (which the PATH already define for that veryBIG.h)

If there any idea to overcome this problem?

UPDATE

I can temporary use Wno-xxx for gcc and delete some [error_ref_number] in flag --diag_error (like CFLAG += --diag_error=550,223,188,177,....,, and I delete 177 for pass this warning in armcc) and makes my compile go on and first fix others warnings, but I do need fix ALL warning.

How Chen
  • 1,340
  • 2
  • 17
  • 37
  • 1
    is it acceptable to suppress such warning in your makefile? using -Wno-unused-variable – tristan Jan 03 '14 at 06:19
  • @tristan, currently no, because this project QA required **ALL** warning free. I use your way to temporary make compile goes on and fix others warning first, I use `-Wno-unused-variable` for `gcc` and I delete some `[error_ref_number]` in flag `--diag_error=` for `armcc` – How Chen Jan 03 '14 at 06:20
  • @HowChen : I think **all warning free** requirement means removing all those warnings which may create potential bugs in future. I don't think a few extra variables allocated statically can create problem. I welcome your suggestions regarding scenarios where they may create problem. – 0xF1 Jan 03 '14 at 06:23
  • Can you edit the header file to conditionally declare those variables, when some `MACRO` is defined, And define/undefine same `MACRO` in your C file before including the header. – 0xF1 Jan 03 '14 at 06:27
  • @MadHatter, thanks for you suggestion, you means `variable 'xxx' was declared but never referenced` have no **RISK**?? – How Chen Jan 03 '14 at 06:29
  • 1
    @MadHatter: The fact that the programmer at one point thought those variables were necessary but eventually didn't reference them is a potential bug in itself. Perhaps some refactoring that has been done halfway, leaving algorithms in unstable state. Perhaps a typo in a macro. In any case, it's a code smell. – DevSolar Jan 03 '14 at 06:32
  • @HowChen : I have suggested one method in my other comment. – 0xF1 Jan 03 '14 at 06:34
  • fwiw: you may suppress this warning in specific compile unit by using the gcc directive #pragma GCC diagnostic ignored "-Wunused-variable" – tristan Jan 03 '14 at 06:35
  • @DevSolar : As OP described in his problem (or As I understood it), the variables **are used** but not neccessarily all are used by same C source. However, the header is included in all the C files. – 0xF1 Jan 03 '14 at 06:36
  • You are trapped in a very bad design choice of your vendor. If these are really only integer constants that they want to make accessible, they should have chosen to use `enum` values. If you are thinking of scripting that file you might just do this: change all `static const int toto = something` to `enum { toto = something }`. – Jens Gustedt Jan 03 '14 at 08:37

3 Answers3

2

AFAIK, the warning variable 'xxx' was declared but never referenced has NO RISK at all for modern devices. The only threat is that the variable may take up a little memory space when the program is loaded, even the smallest modern machines won't suffer OOM with just that little memory waste. BTW modern compilers will optimize that for you, why won't they since the compiler is already warning you about it. You can just ignore the warning.

If you find the warning annoying, just add the -Wno-unused-variable flag during compilation.

Edit: As Alex says in the comment, I'm wrong. But you can see, that even that little risk I mentioned is fake. So just relax.

Almost all open source projects I know will have unreferenced variables, and I don't see any one making much effort to eliminate that.

Edit Again: Alright, I see that you need absolute warning free. Well the only solution I can think of that requires you less hours of work is to use #define macros.

You make blocks of #ifdef/#else/#endif in your header file, and add #defines in your C files. But then you still have to use lots of time figuring out the dependencies.

Your header file would look something like this:

#ifdef __A__
static const int var_used_in_A;
#endif
#ifdef __B__
static const int var_used_in_B;
#endif
#ifdef __EXTRA__
static const int var_used_in_both;
#endif

and your A.c file would look something like this:

#define __A__
#define __EXTRA__
#include "BigHeader.h"
.....

That how the glext.h works for OpenGL. This is better than breaking into lots of smaller header files, as you can see the dependencies clearly with the MACROS, while lots of files will require you to make good documentation. And Macros are more flexible than files.

It would be nice if you can negotiate with the VENDOR you mentioned for them to always tell you the difference they made, and you can just add those to the correct place. If you can't just keep histories of the original VeryBIG.h and use a diff tool to examine the changes of the new one.

TwilightSun
  • 2,275
  • 2
  • 18
  • 27
1

If you care about memory usage to the point where every bit matters, then you probably should break up that header file into many small pieces, because there is no actual guarantee that the compiler won't emit every single one of those static variables and functions over and over in every single .c file even though only a few of them are used. (The as-if rule says the compiler may delete all the unused statics, but nothing says it has to.)

In your shoes I would probably write some sort of script which would automatically do the break-up; then I wouldn't have to do it all over again when new releases happened.

zwol
  • 135,547
  • 38
  • 252
  • 361
0

Can you write?

static_assert(x == x);

or

assert(x == x);

These are removed at compile time.

Eyal
  • 5,728
  • 7
  • 43
  • 70