c - 在 C 标准库中转发声明实体?

标签 c language-lawyer forward-declaration

转发声明 C 标准库提供的结构和函数是否合法?

我的背景是 C++,答案是否定的。这样做的主要原因是 C++ 标准库强制要求的结构或类可以是幕后的模板,并且可能具有“ secret ”模板参数,因此无法使用朴素的非模板声明进行正确声明。即使用户确实弄清楚如何在特定实现的特定版本中转发声明特定实体,该实现也没有义务在未来版本中不破坏该声明。

我手边没有任何 C 标准的副本,但显然 C 中没有模板。

那么在C标准库中转发声明实体是否合法?

C++ 标准库中的实体可能无法前向声明的另一个原因是实现提供的 header 不需要遵循正常规则。例如,在最近的一个问题中,我询问实现提供的 C++ header 是否需要是实际文件,答案是否定的。我不知道其中是否适用于 C。

C 和 C++ 都使用 C 标准库,但对于这个问题,我只问 C。

最佳答案

结构的前向声明在 C 中始终是允许的。但是,可以这种方式使用的类型并不多。例如,您不能仅仅因为未指定结构的标记名称而对 FILE 使用前向声明(理论上,它可能根本不是结构)。

n1570 第 7.1.4 节第 2 段允许您对函数执行相同的操作:

Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.

这在过去很常见。我认为这里的原因是硬盘驱动器速度慢,更少的 #include 意味着更快的编译时间。但这已经不是 1980 年代了,我们都拥有快速的 CPU 和快速的硬盘驱动器,所以一些 #include 甚至都没有被注意到。

void *malloc(size_t);
void abort(void);

/* my code here */

关于c - 在 C 标准库中转发声明实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27720258/

相关文章:

linux - dup2 真的可以返回 EINTR 吗?

c - Libcurl ftp通配符上传

java - 从未排序数组构建最大堆会遵循二叉树属性吗?

c++ - 如何在 cpp 源文件中链接静态库?

c++ - 在 C++ 中,是否可以将一个类声明为从另一个类继承?

c++ - 将前向声明的类型转换为 void 是否合法?

c++ - 前向声明和全局命名空间声明

c - 'timespec' 结构的 Visual Studio 错误

c++ - 我可以通过placement-new 覆盖const 对象吗?

c++ - 内联函数体的潜在评估和模板成员的实例化