【问题标题】:Assignment of incompatible type and different namespaces in CC中不兼容类型和不同命名空间的分配
【发布时间】:2014-01-22 23:00:46
【问题描述】:

我有一个具有以下结构的链式哈希表:

typedef struct{
    char* phrase; 
    struct phrase_struct* next; 
}phrase_struct;

我对这个结构的直接关注是指针实际上引用了一个可能尚未定义的 typedef .. 但它已编译,所以我认为它是有效的语法。我有几个函数可以分配内存并操作指向下一个节点的指针next

考虑以下类型的指针和自动分配的结构:

phrase_struct* ptr1

phrase_struct* ptr2

phrase_struct test_s;

如果我做了以下作业:

ptr1 = &test_s

ptr2 = test_s.next;

我会不断收到错误,抱怨类型分配不兼容:

'=' : incompatible types - from 'phrase_struct *' to 'phrase_struct *'

然后它击中了我.. 我记得以前读过一些关于 typedef 的命名空间和实际结构名称是独立的。


typedef struct test{
    char* phrase; 
    struct test* next; 
}phrase_struct;

将结构定义更改为此修复了所有警告。

有人能解释一下吗?

【问题讨论】:

  • 另一个要考虑的选项:删除 typedef 并将类型称为 struct phase_struct。但是如果你决定使用typedef(给类型一个更短的名称),typedef 名称可以与标签相同:typedef struct phase_struct { /* ... */ } phase_struct;

标签: c struct typedef


【解决方案1】:

这个定义

typedef struct{                 // 1
    char* phrase; 
    struct phrase_struct* next; // 2
}phrase_struct;                 // 3

定义了三件事:

  1. 匿名结构
  2. 一个成员,它是一个名为struct phrase_struct前向声明结构的指针
  3. typedef 用于名为 phrase_struct 的匿名结构

当您引用一个普通的phrase_struct 时,它指的是typedef。每当您引用struct typedef 时,它指的是struct 标签命名空间内名为phrase_struct 的结构;此结构已被前向声明(在 (2) 中)并且是不完整的类型,但实际上尚未完全定义。

不幸的是,错误消息令人困惑。错误想说的是:

'=' : incompatible types - from 'struct phrase_struct *' to the typedef
      'phrase_struct *'

因为未定义的、前向声明的结构与已定义的typedef 无关。

正如您所发现的,修复方法很简单:不用定义 anonymous 结构,而是为结构命名,然后在成员定义:

typedef struct phrase_struct{   // 1
    char* phrase;
    struct phrase_struct* next; // 2
}phrase_struct;                 // 3

这定义了:

  1. struct 标记命名空间中名为 struct phrase_struct 的结构
  2. 具有指向 struct phrase_struct 实例的指针类型的成员(即 (1) 中定义的类型)
  3. 一个名为phrase_structtypedef,定义为struct phrase_struct的别名

这很令人困惑,因为标签命名空间(structunionenum)与普通的 typedef 命名空间是分开的。

另请参阅 Difference between struct and typedef struct in C++?What is a typedef enum in Objective-C?

【讨论】:

    【解决方案2】:

    有了这个:

    typedef struct{
        char* phrase; 
        struct phrase_struct* next; 
    }phrase_struct;
    

    您从未定义过struct phrase_struct,因此struct phrase_struct * 是一个指向您可能从未定义过的不完整类型的指针。 phrase_struct 这是一个匿名结构的 typedefd 名称。该匿名结构与struct phrase_struct 不同,因此您的编译器正确指出指针的类型不同。

    当您说“它已编译,因此我认为它是有效的语法”时,这是因为您可以定义指向尚未定义的类型的指针,因为编译器只需要知道指针需要多少内存,它可以在不需要知道类型的细节的情况下弄清楚。但是您必须先为这种类型提供一个定义,然后才能实际创建该类型的任何对象,并且在您可以取消引用指向它的指针以访问其成员等之前。

    因此,谜团在于您确实(或最初确实)具有有效的语法,但该语法并没有按照您的想法执行。

    【讨论】:

      猜你喜欢
      • 2013-09-15
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-31
      • 2018-12-06
      • 1970-01-01
      • 2011-05-29
      • 2011-01-12
      相关资源
      最近更新 更多