Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使gcc警告未定义的结构?_C_Pointers_Gcc_Sizeof_Gcc Warning - Fatal编程技术网

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

如何使gcc警告未定义的结构?,c,pointers,gcc,sizeof,gcc-warning,C,Pointers,Gcc,Sizeof,Gcc Warning,我在.h中定义了一个结构 struct buf_stats { // *** }; 然后在.c文件中 struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ; 其中buf_states为打字错误 尽管我使用了-Wall 我花了3个小时才发现这个错误 如何使gcc警告未定义的结构像这样?在代码中 struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ; 错误的

我在.h中定义了一个结构

struct buf_stats {
   // ***
};
然后在.c文件中

struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ;
其中
buf_states
为打字错误

尽管我使用了
-Wall

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

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

在代码中

  struct buf_stats *bs = malloc(sizeof(struct buf_states*)) ;
错误的原因有很多,比如

  • 您正在使用未定义的类型(如您所述)
  • 您正在分配更少的内存(分配指向类型的指针,而不是类型)
但在这种情况下,对于这种特殊类型的错误,编译器帮不了什么忙,因为

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

  • 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)) ;
但它更健壮,更不容易出错

注:

  • 如果操作数不是类型名,则不需要括号
  • 在更改目标变量的类型时,不需要对该语句进行任何修改

  • 你不能。使用类似于
    struct foo*
    (指向某个结构类型的指针)的表达式将该结构声明为不完整类型。大小未知,但指针的大小不需要它

    也就是说,代码看起来是错误的,因为您需要结构的大小(不是指针的大小),因此使用以下代码:

    struct buf_stats *bs = malloc(sizeof(struct buf_states));
    
    您将得到一个错误

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

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

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

    Heh?你收到的错误信息是什么?@SouravGhosh我想没有错误信息,这就是OP所问的。你想为指针分配足够的空间吗?编译器实际上并不需要它所指向的对象的大小。还是要为结构使用malloc?在这种情况下,还有另一个输入错误,即第二个
    *
    。您甚至可以编写
    struct XXX*bs=malloc(sizeof(struct YYY*))并且您仍然没有得到任何错误。只有当你写
    bs->something
    时,你才会得到一个编译错误。即使你没有输入,它仍然是错误的。可能值得一提的是,
    sizeof*bs
    中的
    *
    并不表示指针,而是一个取消引用
    bs
    是一个指针,因此,
    *bs
    是结构值本身,在这里调用sizeof。此外,注意1是好的,因为它实际上会产生一个类似于@Sato所要求的错误,如果
    struct but_stats
    不完整,或者,
    bs
    是一个类型名而不是变量名。我见过一些平台,它们指向不同大小对象的指针大小不同。(void*是指向任何数据类型的最大指针。)@Joshua:一般来说,指向不同类型的指针可以有不同的表示形式(包括大小),但也有例外:除了限定符之外兼容的类型必须相同,
    void*
    和所有
    char*
    同上,所有
    struct*
    ,以及所有
    联合*
    。请参见C11(n1570)中的6.2.5p28或C99中的p26。@dave_thompson_085:我使用了一个,其中sizeof(char*)==2,而sizeof(const char*)==3!有趣的是;(char*)(const char*)char\u指针无论如何都能工作,即使无法优化转换。