gpt4 book ai didi

c - 使用定义不同于内部使用的外部头文件

转载 作者:太空宇宙 更新时间:2023-11-04 01:20:30 26 4
gpt4 key购买 nike

假设您正在编写一个在内部使用某些数据结构的库,并且只想向用户导出其中的一个子集(或者使用类似 void * 的东西隐藏确切的类型)。库中使用的所有结构和函数的定义都在 header library.h 中,将在构建库时使用。

同时生成 library.h 的另一个副本是否被认为是好的做法,该副本不会在构建过程中使用,而只会被链接到库的用户使用?

例如,假设库在内部使用以下 library.h:

#ifndef LIBRARY_H
#define LIBRARY_H

struct myStruct {
int some_x;
void (*some_callback)(void);
};

typedef struct myStruct *myStruct_t;

#endif

虽然我们想向用户隐藏myStruct的定义,所以我们导出一个头文件library.h,即:

#ifndef LIBRARY_H
#define LIBRARY_H

typedef void *myStruct_t;

#endif

最佳答案

Is it considered good practice to also produce another copy of library.h that would not be used during the build process but only by users linking to the library?

没有。虽然关于你想做的事情的最佳实践的细节可能是一个品味问题,但在构建过程中提供未使用的 header 客观上不是一个好的实践:你冒着引入在构建项目时从未发现的打字错误的风险。

因此,无需详细说明您应该如何组织它,您绝对应该做的是让每个“private” header #include 各自的“ public" header 并且不在私有(private) header 中重复公共(public)声明。对于您的示例,这看起来例如喜欢:

库.h:

#ifndef LIBRARY_H
#define LIBRARY_H

typedef struct myStruct *myStruct_t;
// there's absolutely no need to use void * here. An incomplete struct
// type is perfectly fine as long as only pointers to it are used.

#endif

library_internal.h:

#ifndef LIBRARY_INTERNAL_H
#define LIBRARY_INTERNAL_H
#include "library.h"

struct myStruct {
int some_x;
void (*some_callback)(void);
};

#endif

额外的“最佳实践”说明:

  • 不要将指针隐藏在 typedef 后面。大多数 C 程序员都清楚指针是声明符 的一部分,并希望在有指针时显式看到 指针。取消引用某些看起来 不像指针的东西只会给阅读代码的其他人造成混淆。您还可能会混淆您的库的使用者,让他们期望 myStruct_t 展示按值调用语义。

  • 不要使用 _t 后缀定义您自己的类型。至少在 POSIX 中,这是为(编译器/运行时的)实现保留的。定义一个与 struct 标签同名的类型并没有错。

带有这些附加建议的示例:

库.h:

#ifndef LIBRARY_H
#define LIBRARY_H

typedef struct myStruct myStruct;

#endif

library_internal.h:

#ifndef LIBRARY_INTERNAL_H
#define LIBRARY_INTERNAL_H
#include "library.h"

struct myStruct {
int some_x;
void (*some_callback)(void);
};

#endif

关于c - 使用定义不同于内部使用的外部头文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44614100/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com