GCC 11 在不使用字符串操作时给出 -Wstringop-overflow

GCC 11 gives -Wstringop-overflow when no string operation is used

提问人:Tony Fettes 提问时间:11/9/2021 最后编辑:Tony Fettes 更新时间:10/9/2023 访问量:1004

问:

这是我的代码。

// test.c
#include <stdio.h>

#define ARRAY_SIZE 4

struct example_t {
  int field0;
  int field1;
  int field2;
  int field3;
  int field4;
};

struct example_t func(int *in, int array[ARRAY_SIZE]) {
  struct example_t out;
  return out;
}

int main() {
  int array[ARRAY_SIZE] = { 0, 0, 0, 0 };
  int a = 0;
  struct example_t col = func(&a, array);
  return 0;
}

gcc11.1.0 给出

$ gcc test.c -o test
test.c: In function ‘main’:
test.c:22:26: warning: ‘func’ accessing 16 bytes in a region of size 4 [-Wstringop-overflow=]
   22 |   struct example_t col = func(&a, array);
      |                          ^~~~~~~~~~~~~~~
test.c:22:26: note: referencing argument 2 of type ‘int *’
test.c:14:18: note: in a call to function ‘func’
   14 | struct example_t func(int *in, int array[ARRAY_SIZE]) {
      |                  ^~~~

但事实并非如此。g++

我不明白为什么会出现警告消息,因为我的代码中没有字符串操作,而且我从未读入。arrayfunc

如果 中只有 4 个或更少的字段,GCC 不会抱怨。有人可以解释为什么消息在这里以及如何解决它吗?struct example_t

先谢谢你。

数组 c 函数 gcc 结构

评论

0赞 Tony Fettes 11/9/2021
@user3386109 很抱歉,现在我已经更新了编译器的输出。
1赞 user3386109 11/9/2021
如果初始化,会发生什么情况:struct example_t out = {0};
0赞 Tony Fettes 11/9/2021
@user3386109 gcc 给出了相同的诊断。
4赞 kaylum 11/9/2021
看起来像 gcc12 中解决的 gcc.gnu.org/bugzilla/show_bug.cgi?id=101854。可能仍然值得引用该错误进行记录,以防结果不同。
1赞 kaylum 11/9/2021
仅供参考,godbolt 还确认 gcc 11 有问题,但 gcc trunk 没有。

答:

0赞 masonthedev 10/9/2023 #1

看起来警告与这行代码有关:

struct example_t col = func(&a, array);

即使您没有执行任何字符串操作,编译器也会警告您,因为它看到您正在将 int 数组 (array) 传递给需要 int 数组参数的函数 (func)。该警告指示函数 func 访问的内存可能超过为 array 参数分配的内存。在此上下文中,编译器将数组参数视为可能被不当访问的潜在缓冲区。

您可以更改函数签名:

如果函数 func 实际上不对字符串进行操作,或者需要类似字符串的缓冲区,则可以更改其签名以阐明其意图:

struct example_t func(int *in, int array[ARRAY_SIZE]) {
    struct example_t out;
    // Function code
    return out;
}

需要明确的是,这是为了替换主线中的问题行。

通过明确 func 需要整数数组,可以防止编译器发出警告。