【问题标题】:error: incompatible types when initializing type 'struct ...'错误:初始化类型'struct ...'时类型不兼容
【发布时间】:2016-03-25 12:01:23
【问题描述】:

我有以下代码:

#include "stdio.h"

typedef struct StackEntry StackEntry;
typedef struct StackEntry
{
    int data;
    StackEntry *next;
};

StackEntry* createStack()
{
    return NULL;
}

int main()
{
    StackEntry *stack = createStack(); //Error: incompatible types when initializing type 'struct StackEntry *' using type 'StackEntry'
}

如上所示,我收到错误incompatible types when initializing type 'struct StackEntry *' using type 'StackEntry'。很长一段时间后我正在重新访问C。我在这里做错了什么?

编辑(非常抱歉)

我不必要地简化了一些东西。我觉得这将有助于突出显示错误代码。我原来的设置有很多代码。它也在工作。但现在它坏了。所以我收集了所有相关的代码并放在这里。我应该首先尝试将它们全部放在一个文件中并运行。我很抱歉没有这样做。但现在我已经剥离了所有可能的代码并能够重现错误。这里是:

算法.h

#ifndef ALGORITHMS_H_
#define ALGORITHMS_H_

StackEntry createStack();

#endif /* ALGORITHMS_H_ */

数据结构.h

#ifndef DATASTRUCTURES_H_
#define DATASTRUCTURES_H_

typedef struct StackEntry StackEntry;

struct StackEntry
{
    int data;
    StackEntry *next;
};
#endif /* DATASTRUCTURES_H_ */

stack.c

#include "datastructures.h"
#include "stdio.h"

StackEntry* createStack()
{
    return NULL;
}

Main.c

#include "datastructures.h"
#include "algorithms.h"

int main()
{
    StackEntry *stack = createStack(); //Error: incompatible types when initializing type 'struct StackEntry *' using type 'StackEntry'
    return 0;
}

【问题讨论】:

  • 为什么会有第二个 typedef,因为它会被忽略?
  • 去掉没用的第二个typedef后还有错误吗?
  • 啊我错过了...它不应该存在...顺便说一句为什么编译器不认为它是错误...?
  • 这是 C 还是 C++?它们是两种不同的语言,处理类名的方式不同
  • 哦,这是在.c 文件中

标签: c struct typedef


【解决方案1】:

你需要修复algorithms.h:

#ifndef ALGORITHMS_H
#define ALGORITHMS_H

extern StackEntry *createStack();

#endif /* ALGORITHMS_H */

(extern 不是强制性的,这是一种很好的做法,但您确实需要这个*)。

【讨论】:

    【解决方案2】:

    下面的代码可以编译 - 希望这会有所帮助(VSTO 2013 控制台应用程序)

    #include "stdafx.h"
    
    
    typedef struct StackEntry
    {
        int data;
        StackEntry *next;
    };
    
    StackEntry* createStack()
    {
        return NULL;
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        StackEntry *stack = createStack(); 
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      正如你在评论中所说的你正在使用 Eclipse,我认为 Eclipse 试图比往常更聪明......

      此代码可能会发出警告(警告:typedef 需要名称 [-Wmissing-declarations],因为正如 @GrzegorzSzpetkowski 所解释的,您的第二个 typedef 不包含名称,因此忽略类型定义。

      但足以打扰 Eclipse 迷路并显示不存在的错误。

      【讨论】:

        【解决方案4】:

        StackEntrys 太多。你可以这样做:

        struct _StackEntry; // there is such a struct, no matter where.
        
        struct _StackEntry {
            int a;
            _StackEntry *next; // now the compiler knows that this is a valid type
        }
        
        typedef _StackEntry StackEntry; // add an alias of this type
        

        【讨论】:

        • 以下划线+大写开头的标识符在所有上下文中都是保留的。以下划线开头的标识符在文件范围内保留。 (C11 7.1.2) 确实没有理由不为 struct 标签和 typedef 使用完全相同的名称,因为它们位于不同的名称空间中;给标签一个修饰的名字只会增加混乱。
        • 大声笑,说“StackEntrys 太多”,然后发布比原始代码更多 StackEntry 的代码
        • @Leushenko,这不应该增加太多混淆,因为据我了解,代码中只会使用StackEntry,并且带有下划线的类型不会混淆任何人。
        • @M.M、StackEntry 和 _StackEntry 是不同的,不是吗?
        • 是的,但对原版没有任何改进
        【解决方案5】:

        我不知道这是否是答案。我希望我能发表评论,但不幸的是,我只是这个网站的新手。我会尝试从您的结构定义中删除 typedef:

        typedef struct StackEntry StackEntry;
        struct StackEntry
        {
            int data;
            StackEntry *next;
        };
        

        【讨论】:

        • 删除typedef 是个好主意,但是它没有任何效果,所以这不应该改变编译器的输出。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        相关资源
        最近更新 更多