简体   繁体   English

在C中隐藏类型定义

[英]Hide type definition in C

I have a .c file (a library of functions) with a function and a definition like this: 我有一个.c文件(一个函数库),带有一个函数和一个这样的定义:

typedef long double big;
big foo(int x) { ... }

I want to create an interface of this library, an .h . 我想创建这个库的接口, .h So I do: 所以我做:

typedef long double big;
big foo(int);

and remove the typedef long double big; 并删除typedef long double big; from the .c file. .c文件。 But by doing so I give away the type definition of big in my interface, so it's not really a clean interface. 但是通过这样做,我在接口中放弃了big的类型定义,因此它并不是真正的干净接口。 Any ideas how to fix that? 任何想法如何解决?

I know I could do this in my .c file: 我知道我可以在.c文件中执行此操作:

struct foo {
  long double;
};

and then in the .h file do: 然后在.h文件中执行以下操作:

typedef struct foo big;
big foo(int);

But it seems waste to create a struct for just one field, plus I should use the . 但是为一个字段创建一个struct似乎很浪费,而且我应该使用. operator whenever I want to read a big . 每当我想阅读big

If the type is never going to get more complex than long double , then it probably isn't worth having conniptions about hiding it more. 如果类型永远不会比long double复杂,那么就不值得再隐藏更多。 If it might need to become more complex, then you can consider using an opaque type. 如果可能需要变得更复杂,则可以考虑使用不透明类型。 In your public header, big.h , you use: 在公共头文件big.h ,使用:

#ifndef BIG_H_INCLUDED
#define BIG_H_INCLUDED
typedef struct big big_t;

extern big_t *foo(int);

...

#endif

All the functions will take and return pointers to the big_t type. 所有函数都将采用并返回指向big_t类型的指针。 This is all you can do with incomplete types like that. 这就是使用不完整类型所做的所有工作。 Note that your customers cannot allocate any big_t values for themselves; 请注意,您的客户无法为其分配任何big_t值; they don't know how big the type is. 他们不知道类型有多大。 It means you'll probably end up with functions such as: 这意味着您可能最终会遇到以下功能:

extern big_t *big_create(void);
extern void   big_destroy(big_t *value);

to create and destroy big_t values. 创建和销毁big_t值。 Then they'll be able to do arithmetic with: 然后他们将能够使用以下方法进行算术运算:

extern big_errno_t big_add(const big_t *lhs, const big_t *rhs, big_t *result);

Etc. But because they only have an opaque, incomplete type, they cannot reliably go messing around inside a big_t structure. 等等,但是因为它们只有不透明的,不完整的类型,所以它们不能可靠地在big_t结构内big_t But note that you are constrained to using pointers in the interface. 但是请注意,您只能在接口中使用指针。 Passing or returning values requires complete types, and if the type is complete, users can investigate its inner workings. 传递或返回值需要完整的类型,如果类型完整,则用户可以调查其内部工作方式。

In the implementation header, bigimpl.h , you'll have: 在实现标头bigimpl.h ,您将具有:

#ifndef BIGIMPL_H_INCLUDED
#define BIGIMPL_H_INCLUDED
#include "big.h"

struct big
{
    ...whatever the details actually are...
};

#endif

And your implementation code will only include bigimpl.h , but that includes big.h . 而且您的实现代码将仅包含bigimpl.h ,但其中包含big.h The main issue here is making sure you know how the memory allocations are handled. 这里的主要问题是确保您知道如何处理内存分配。

Sometimes this technique is worthwhile. 有时这种技术是值得的。 Often it is not really necessary. 通常,这并不是真正必要的。 You'll need to make the assessment for yourself. 您需要自己进行评估。

and remove the typedef long double big; 并删除typedef long double big; from the .c file. 从.c文件。 But by doing so I give away the type definition of big in my interface, so it's not really a clean interface. 但是通过这样做,我在接口中放弃了big的类型定义,因此它并不是真正的干净接口。

How so? 怎么会这样? Who cares if users of your code can see the typedef? 谁在乎您的代码用户是否可以看到typedef? How does it hurt... anything? 它怎么疼...什么? They need a way to use your typedef and this is how it is done. 他们需要一种使用typedef的方法,这就是完成方法。 Sounds like a theoretical problem to me that has no appreciable ill effects. 对我来说,这听起来像是一个理论上的问题,没有明显的不良影响。 You're worrying about the wrong thing(s). 您担心的是错误的事情。

But tit seems waste to create a struct for just one field, plus I should use the . 但是tit似乎只为一个字段创建结构,这很浪费,而且我应该使用。 operator whenever I want to read a big. 每当我想阅读大的运算符时。

Yup, that is silly. 是的,这很愚蠢。 Also, now you've given away the definition of your struct! 另外,现在您已经放弃了struct的定义! Oh no! 不好了! How is that any different than exposing the typedef (or any other type)? 与公开typedef(或任何其他类型)有什么不同?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM