Following shows two errors generated by GCC:
In file included from /home/omar/Desktop/Lovelace/src/main.cpp:22:
/home/omar/Desktop/Lovelace/include/stb/stb_image.h: In function ‘void* stbi__load_gif_main(stbi__context*, int**, int*, int*,
int*, int*, int)’:
/home/omar/Desktop/Lovelace/include/stb/stb_image.h:6778:11: **error: variable ‘out_size’ set but not used** [-Werror=unused-but-set-variable]
6778 | int out_size = 0;
| ^~~~~~~~
/home/omar/Desktop/Lovelace/include/stb/stb_image.h:6779:11: **error: variable ‘delays_size’ set but not used** [-Werror=unused-but-set-variable]
6779 | int delays_size = 0;
| ^~~~~~~~~~~
cc1plus: all warnings being treated as errors
make[2]: *** [CMakeFiles/lovelace.dir/build.make:102: CMakeFiles/lovelace.dir/src/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/lovelace.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Yet there doesn't seem to be any problem as the variables are indeed used:
int out_size = 0;
int delays_size = 0;
memset(&g, 0, sizeof(g));
if (delays) {
*delays = 0;
}
do {
u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
if (u) {
*x = g.w;
*y = g.h;
++layers;
stride = g.w * g.h * 4;
if (out) {
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
if (NULL == tmp) {
STBI_FREE(g.out);
STBI_FREE(g.history);
STBI_FREE(g.background);
return stbi__errpuc("outofmem", "Out of memory");
}
else {
out = (stbi_uc*) tmp;
out_size = layers * stride;
}
if (delays) {
*delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
delays_size = layers * sizeof(int);
}
} else {
out = (stbi_uc*)stbi__malloc( layers * stride );
out_size = layers * stride;
if (delays) {
*delays = (int*) stbi__malloc( layers * sizeof(int) );
delays_size = layers * sizeof(int);
}
} int out_size = 0;
Is this a compiler bug?
Edit: Version of GCC is 9.3.0
OS: Linux Mint latest
The code initialises and modifies out_size
and delay_size
but does not use them (they are only ever written, and never read). The one place it appears to be used is the STBI_REALLOC_SIZED()
calls, but STBI_REALLOC_SIZED
is a macro defined thus:
#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
so oldsz
is unused.
Compiling without -Wunused-variable
(or one of the -W
options that imply this) and -Werror
is an unsatisfactory solution as it will suppress warnings in your own code that you might want. Had this been normal library code rather the static functions in a header (a nasty thing in itself), then you could compile the third-party code with different options that your own code. The simplest solution is to modify the stb_image.h file such that it has:
int out_size = 0; out_size = out_size ;
int delays_size = 0; delays_size = delays_size ;
or
int out_size = 0; (void)out_size ;
int delays_size = 0; (void)delays_size ;
It turns out the header already has a macro for that:
int out_size = 0; STBI_NOTUSED(out_size) ;
int delays_size = 0; STBI_NOTUSED(delays_size) ;
That will "use" the variables in a manner that has no real effect and can be optimised out (though clearly that is not a concern if you choose to use this hideous abuse of a header file). The dummy use suppresses the warning.
Ordinarily you might not want to change a header to a third-party library, but in this case the header is the library so there is no risk of inconsistency if say it weer a header for an shared object library. The change is visible to all code that uses it. The only issue is that you might have to re-implement the fix if you adopt an updated version. One solution to that is to submit a change request to the author, so the problem goes away for everyone.