我有以下代码,在x.cpp
,g ++ 5.3.0中的最后一行编译conflicting declaration 'typedef struct THE_TYPE_STRUCT THE_TYPE'
(y.h
时抛出编译错误:
// x.h file
struct THE_TYPE;
class C{
THE_TYPE * t;
};
// x.cpp file
#include "x.h"
extern "C"{
#include "y.h"
}
// y.h file
struct THE_TYPE_STRUCT {
int x;
};
typedef struct THE_TYPE_STRUCT THE_TYPE;
文件y.h
是一个C头,由于名称与其他头文件冲突,因此无法包含在头x.h
的开头,因此我必须为{{1 }}。似乎它并不完全正确。 如何正确完成?
答案 0 :(得分:1)
C与C ++不同,并且有不同的规则(例如,typedef struct THE_TYPE THE_TYPE;
无用 - 在C ++中是隐式的,但在C中是有意义的。)
您应该生成预处理表单(例如使用g++ -C -E x.cpp > x.ii
)然后进行研究。一个可能的技巧是删除行信息(从#
开始),运行
g++ -C -E x.cpp | grep -v '^#' > x.ii
然后使用g++ -Wall -c x.ii
重新编译,并查看x.ii
中的错误位置
在不知道所涉及的实际文件的情况下,我们无法帮助(例如某些文件可能有一些#define THE_TYPE
)。
我该如何正确地做到这一点?
在C ++中,您可能会使用namespace
- s(特别是在您自己的文件中)并避免使用宏。
在C中,您可能应该编辑文件,我建议在您自己的代码中为每个公共名称添加一个公共前缀。您可以从GTK获取灵感,其中每个名称都以Gtk
或GTK
或_GTK
等开头......
通常,您需要一些一致的命名约定,并且您可能需要编辑所有文件。
答案 1 :(得分:0)
更改
struct THE_TYPE_STRUCT {
int x;
};
typedef struct THE_TYPE_STRUCT THE_TYPE;
到
typedef struct THE_TYPE_STRUCT {
int x;
}THE_TYPE;
答案 2 :(得分:0)
我在当前项目中使用以下方案将一些c++11代码混合到c11代码库中:
basedecl.h (随处可见):
// [...]
#ifdef __cplusplus
# define pocaslibs___cdecl extern "C"
# define DECLDATA
# define C_CLASS_DECL(t) struct t
# define C_ENUM_DECL(t) enum t
#else
# define pocaslibs___cdecl
# define DECLDATA extern
# define C_CLASS_DECL(t) typedef struct t t
# define C_ENUM_DECL(t) typedef enum t t
#endif
// [...]
正向声明struct
类型(也用于"私有"类型):
C_CLASS_DECL(PG_Menu);
C_CLASS_DECL(PG_Window);
宣布"公众" struct
种类:
C_CLASS_DECL(PG_Bounds);
struct PG_Bounds
{
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
};
对两种语言都很有效。该宏名为C_CLASS_DECL
,因为在我的代码库中,这实际上用于在c中创建OO类。如果你的用例与OO无关,那么最好考虑一个更好的名字;)