如何让gcc警告undefined结构?

Sat*_*ato 20 c gcc pointers sizeof gcc-warning

我有一个在.h中定义的结构

struct buf_stats {
   // ***
};
Run Code Online (Sandbox Code Playgroud)

然后在.c文件中

struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ;
Run Code Online (Sandbox Code Playgroud)

哪里buf_states是拼写错误.

但gcc并没有警告我,虽然我用过 -Wall

这个错误/错字花了我3个小时才发现.

如何让gcc像这样警告未定义的结构?

Sou*_*osh 35

在你的代码中

  struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ;
Run Code Online (Sandbox Code Playgroud)

因为很多原因是错误的

  • 您正在使用未定义的类型(如您所述)
  • 你正在分配更少的内存(分配指针类型而不是类型)

但是,对于这种特殊类型的错误,编译器对_this_case没有多大帮助

  • 平台中指向(任何)类型的指针具有已定义的大小,因为结构(即它指向的变量的类型)不需要完整(定义).这就是我们可以拥有自引用结构的原因,对吗?

  • malloc()不知道目标变量类型.它只读取所需大小的参数,将指针(类型void *)返回到已分配的内存,并在赋值时将其更改为目标类型.它不可能用分配的内存大小来计算目标大小(类型)的不匹配.

避免这些类型错误的最方便和最简单的方法是,不要直接使用硬编码类型作为操作数sizeof,而是使用变量引用.

就像是

 struct buf_stats *bs = malloc(sizeof *bs) ; // you can write that as (sizeof (*bs)) also
                                             // sizeof *bs === sizeof (struct buf_stats)
Run Code Online (Sandbox Code Playgroud)

这相当于

 struct buf_stats *bs = malloc(sizeof(struct buf_stats)) ;
Run Code Online (Sandbox Code Playgroud)

但更健壮,更不容易出错.

笔记:

  1. 如果操作数不是类型名称,则不需要括号.
  2. 在更改目标变量的类型时,此语句不需要任何修改bs.

  • 值得一提的是,`sizeof*bs`中的`*`表示*不*表示指针,而是表示取消引用.`bs`是一个指针,所以`*bs`是结构值本身,在这里调用sizeof. (2认同)

小智 17

你不能.使用像struct foo *(指向某个结构类型的指针)这样的表达式将结构声明不完整类型.大小未知,但指针的大小不是必需的.

也就是说,代码看起来不对,因为你需要结构的大小(而不是指针的大小),所以使用以下代码:

struct buf_stats *bs = malloc(sizeof(struct buf_states));
Run Code Online (Sandbox Code Playgroud)

你会收到一个错误.

有一种更好的方法来编写这样的代码:

struct buf_stats *bs = malloc(sizeof *bs);
Run Code Online (Sandbox Code Playgroud)

表达式*bs具有正确的类型sizeof,即使您稍后更改类型也是如此.