C++ 中的冲突声明

Conflicting declaration in c++

我有一个cpp文件如下:

#include <iostream> 

#include "i.h"

using namespace std; 

typedef struct abc{
int a1;
int b1;
} abc_t, *abc;

void fun(abc x){
cout<<x->a1;
}

int main(){
abc val;
fun(val);
return 0;
}

i.h 文件:

struct abc;

void fff(struct abc);

当我编译代码时出现以下错误:

t.cpp:8: error: conflicting declaration ‘typedef struct abc* abc’

t.cpp:5: error: ‘struct abc’ has a previous declaration as ‘struct abc’

t.cpp: In function ‘void fun(abc)’:

t.cpp:11: error: base operand of ‘->’ has non-pointer type ‘abc’

如果我将 cpp 文件保存为 c 文件并使用 c 编译器进行编译,那么一切正常。 c++ 编译器有什么问题?

这个

struct abc;

在 C++ 中声明类型 struct abc 以及类型 abc,然后与 typedef'ing ...*abc 再次发生冲突。

在 C 中,它只是声明 struct abc,因此 typedef'ing ...*abc 不会产生重复声明。

您已使用 typedefabc 声明为结构和指向结构的指针。这与做的一样:

struct abc {...};
typedef abc abc_t; // ok, abc_t is now an alias for abc
typedef abc *abc;  // error

跳过 typedefabc_t*abc 并使用 class(所有成员默认为 public)abc 作为-是。

i.h

struct abc {
    int a1 = 0;
    int b1 = 0;
};

void fun(const abc& x);

i.cpp

#include <iostream>
#include "i.h"

void fun(const abc& x) {
    std::cout << x.a1 << "\n";
}

main.cpp

#include <iostream>    
#include "i.h"

int main(){
    abc val;
    fun(val);
    return 0;
}

在C中,这个:

struct abc
{
   int a1;
   int b1;
};

创建类型 struct abc(粗略地说),但不是类型 abc.

这就是为什么你使用 typedef 技巧来创建一个我们可以使用的类型而不必到处写 struct:

typedef struct abc{
   int a1;
   int b1;
} abc_t;

现在您也有了类型 abc_t,它与 struct abc 相同。还是没有类型 abc.

因此,当您添加名为 abc 的指针声明时,这是有效的,因为名称尚未被采用。


在 C++ 中,原始声明创建了一个名为 abc 的类型。不需要 typedef 技巧,并且您对名为 abc 的指针的声明无效,因为名称 abc 已被占用。


解决方案

您可以像这样消除名称歧义(并消除代码的混淆):

struct abc
{
   int a1;
   int b1;
};
typedef struct abc abc_t;
abc_t* ptr_to_abc;

或者,如果您正在编写 C++ 并且不需要 C compat,只需这样做:

struct abc
{
   int a1;
   int b1;
};

abc* ptr_to_abc;