2017-09-05 101 views
20

我在.H如何让gcc警告未定义的结构?

struct buf_stats { 
    // *** 
}; 

限定的结构然后在.c文件

struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ; 

其中buf_states是一个错字。

但GCC不提醒我,虽然我以前-Wall

和这个bug /错字我花了3个小时找到。

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

+0

嘿?你得到的错误信息是什么? –

+0

@SouravGhosh我认为没有错误信息,这是OP询问的。 – Yunnosch

+17

窦想给malloc足够的空间作为指针吗?编译器并不真正需要它指向的大小。或者你想malloc的结构?在这种情况下,还有另一个错字,第二个“*”。 – Yunnosch

回答

36

在你的代码

struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ; 

是错误的原因有很多,像

  • 您使用的是未定义的类型(如你所提到的)
  • 您分配方式较少的内存(分配的一个指针类型而不是类型

但你编译器不能帮助很多在_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) 

这相当于

struct buf_stats *bs = malloc(sizeof(struct buf_stats)) ; 

但是更强大和更不容易出错。

注:

  1. 如果操作数不是类型名称你不需要括号。
  2. 此声明在更改目标变量bs的类型后无需进行任何修改。
+2

可能值得一提的是'sizeof * bs'中的'*'不*表示一个指针,而是一个取消引用。 'bs'是一个指针,所以'* bs'是结构体本身的值,在这里调用sizeof。 – tomsmeding

+0

此外,注释1还是不错的,因为如果'struct but_stats'没有完成,或者'bs'是类型名称而不是变量名称,它实际上会产生类似于@Sato要求的错误。 – Leushenko

+1

我见过指向不同尺寸的东西的指针是不同大小的平台。 (void *是指向任何数据类型的最大指针,以使其工作。) – Joshua

17

你不能。使用类似struct foo *(指向某种结构类型的指针)的表达式声明该结构为不完整类型。尺寸未知,但对于指针的尺寸没有必要。

这就是说,代码看起来错误的,因为你需要的大小结构的指针的大小),所以用下面的代码:

struct buf_stats *bs = malloc(sizeof(struct buf_states)); 

,你会得到一个错误

有写这样的代码有更好的方式:

struct buf_stats *bs = malloc(sizeof *bs); 

表达*bs具有正确的类型sizeof,即使您以后更改类型。