隐藏 C 结构体定义
这是我的设置:
在 public.h 中:
#ifndef PUBLIC_H_
#define PUBLIC_H_
#include "func.h"
/*extern typedef struct _my_private_struct PRIVATE_;*/
typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */
#endif
在 struct.h
#ifndef STRUCT_H_
#define STRUCT_H_
struct _my_private_struct {
int i;
};
#endif
中 在 func.h 中:
#ifndef FUNC_H_
#define FUNC_H_
#include "struct.h"
/* typedef struct _my_private_struct PRIVATE_; */
extern PRIVATE_ * get_new(int);
#endif
在 func.c 中:
#include <stdlib.h>
#include "func.h"
PRIVATE_ * get_new(int i)
{
PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_));
if (p == NULL) return NULL;
p->i = i;
return p;
}
在 main.c 中:
#include "public.h"
int main(int argc, char ** argv)
{
PRIVATE_ *p = get_new(2);
return 0;
}
当我使用 GCC 编译这些文件时,我收到此错误:
OLD COMPILE ERROR
声明说明符中的多个存储类
编辑后编译错误
“*”标记之前应有“=”、“,”、“;”、“asm”或“__attribute__”
有人可以帮我/解释一下为什么我会遇到这个问题以及如何修复它吗?
Here is my setup:
In public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
#include "func.h"
/*extern typedef struct _my_private_struct PRIVATE_;*/
typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */
#endif
In struct.h
#ifndef STRUCT_H_
#define STRUCT_H_
struct _my_private_struct {
int i;
};
#endif
In func.h:
#ifndef FUNC_H_
#define FUNC_H_
#include "struct.h"
/* typedef struct _my_private_struct PRIVATE_; */
extern PRIVATE_ * get_new(int);
#endif
In func.c:
#include <stdlib.h>
#include "func.h"
PRIVATE_ * get_new(int i)
{
PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_));
if (p == NULL) return NULL;
p->i = i;
return p;
}
In main.c:
#include "public.h"
int main(int argc, char ** argv)
{
PRIVATE_ *p = get_new(2);
return 0;
}
When I compile those file with GCC I'm getting this error:
OLD COMPILE ERROR
multiple storage classes in declaration specifiers
COMPILE ERROR AFTER EDIT
expected '=', ',', ';', 'asm', or '__attribute__' before '*' token
Can someone help me out/explain why I'm getting this and how to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
其他答案很好地涵盖了您的问题。不过,请允许我补充一下并回答您的最新评论:
虽然该错误是不言自明的,但可能不太清楚为什么会发生这种情况。考虑一下当您包含 public.h 时会发生什么:
如果您跟踪它并完全扩展预处理器,您将得到以下结果:
现在应该很明显为什么您会遇到问题。如果 func.h 中没有 typedef,您的
get_new
原型就会失败,因为它还没有看到PRIVATE
。 OTOH,如果您保留 typedef,那么您已经定义了两次。另外,看起来您正在尝试使该结构对其他代码和模块保持私有。即使您确实修复了构建错误,您也没有真正实现该封装。考虑一下:
如果您希望 C 中的数据隐私,请考虑不透明的指针设计。我建议像这样重组您的来源:
现在,如果您尝试这样做:
编辑:回答下面OP的评论。
如果您在多个编译单元中实现了私有结构的方法,您仍然可以通过将私有的定义移动到专用标头来使其工作:
实现私有结构“对象”的源文件将包括“func_implementation.h”。使用 private 的外部客户端代码将仅包含“func.h”。
The other answers cover your problem pretty well. However, allow me to add to them and answer your latest comment:
While the error is self-explanatory it's probably less clear why that's happening. Consider what happens when you include public.h:
If you trace through this and fully expand the preprocessor, this is what you'll get:
It should now be obvious why you're running into problems. Without the typedef in func.h, your
get_new
prototype fails because it hasn't seenPRIVATE
yet. OTOH, if you leave the typedef in you've defined it twice.Also, it looks like you're trying to keep that structure private from other code and modules. Even if you do fix the build errors you haven't really achieved that encapsulation. Consider this:
If you want data privacy in C consider an opaque pointer design. I recommend restructuring your source like this:
Now if you try this:
Edit: To answer the OP's comment below.
If you have private struct's methods implemented in more than one compilation unit you can still make it work by moving private's definition to a dedicated header:
Source files that implement your struct private 'object' will include 'func_implementation.h'. External client code that uses private will include 'func.h' only.
;
结束typedef
语句,extern typedef
没有任何意义,只需执行typedef
即可。typedef
statement with a;
extern typedef
makes no sense, just do atypedef
.当前语法不正确,您需要在 typedef 和结构后面添加分号。
The current syntax is incorrect, you need to put a semicolon after the typedefs and the structs.
有一个';' typedef 之后缺失。
编辑:
不要使用带前导下划线的名称。它们是为语言或实现保留的。
There is a ';' missing after the typedef.
EDIT:
Don't use names with a leading underscore. They are reserved for the language or the implementation.