0

下面显示了 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

然而似乎没有任何问题,因为确实使用了变量:

  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;

这是编译器错误吗?

编辑:GCC 的版本是 9.3.0

操作系统:Linux Mint 最新

4

3 回答 3

0

代码初始化和修改out_sizedelay_size但不使用它们(它们只被写入,从不读取)。它似乎被使用的一个地方是STBI_REALLOC_SIZED()调用,但STBI_REALLOC_SIZED它是一个这样定义的宏:

#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)

所以oldsz未使用。

-Wunused-variable在没有(或-W暗示这一点的选项 之一)的情况下进行编译并且-Werror是一个不令人满意的解决方案,因为它会抑制您自己的代码中可能需要的警告。如果这是正常的库代码而不是头文件中的静态函数(本身就是一件讨厌的事情),那么您可以使用与您自己的代码不同的选项来编译第三方代码。最简单的解决方案是修改 stb_image.h 文件,使其具有:

int out_size = 0; out_size = out_size ;
int delays_size = 0; delays_size = delays_size ;

或者

int out_size = 0; (void)out_size ;
int delays_size = 0; (void)delays_size ;

事实证明,标题已经有一个宏:

int out_size = 0; STBI_NOTUSED(out_size) ;
int delays_size = 0; STBI_NOTUSED(delays_size) ;

这将以一种没有实际效果并且可以优化的方式“使用”变量(尽管如果您选择使用这种对头文件的可怕滥用,显然这不是问题)。虚拟使用会抑制警告。

通常,您可能不想将标头更改为第三方库,但在这种情况下,标头就是库,因此如果说它是共享对象库的标头,则不存在不一致的风险。所有使用它的代码都可以看到更改。唯一的问题是,如果您采用更新版本,您可能必须重新实施修复。一种解决方案是向作者提交更改请求,这样每个人的问题都会消失。

于 2021-01-23T21:00:15.770 回答
0

@Cliffort 在他的回答中写的一切都是正确的,但是(使用 gcc)而不是(void)很难搜索,因为它也会显示没有参数的函数我会使用

int aUnused __attribute__((unused));当我看到代码时,它是不言自明的,而且很容易搜索。

(void) 有时会产生一些副作用,例如为(void)variableif variableis生成死代码volatile

https://godbolt.org/z/MrKW1d

于 2021-01-23T21:29:26.670 回答
0

似乎通过使用stbi__load_gif_main(...),会生成警告。这不是编译器的错,也不是你的错。

我复制了这个并得到了相同的结果。

如果不深入研究原因,您可以通过不带标志的编译来解决这个问题-Werror

任何可以首先填写警告的原因的人,请填写。

于 2021-01-23T20:28:17.580 回答