C 中的空结构

Empty structs in C

http://c0x.coding-guidelines.com/6.7.2.1.html:

1401 If the struct-declaration-list contains no named members, the behavior is undefined.

这是否意味着以下是非法的?

struct C { };

或者是什么意思?

我使用 Convention=>C Ada 指针指向一个空结构(实际上是空 Ada 记录)来代替 void* 在我的 C 库绑定中提供服务(因为没有 void* 在阿达)。我想知道这是否不正确。

我误会了什么?


另见 "Do not pass or return structs with no fields of non-zero size to extern (C) functions. According to C11 6.7.2.1p8 this is undefined behavior." https://dlang.org/spec/struct.html

在 C 中很少有非法的,这意味着你不能这样做。相反,C 标准没有定义很多事情,这意味着,如果您执行它们,C 标准并没有说明会发生什么。没有命名成员的结构就是这样。

C 2018 6.7.2.1 8 说,部分:

If the struct-declaration-list does not contain any named members, either directly or via an anonymous structure or anonymous union, the behavior is undefined.

如果您需要某些东西作为“未知类型”并且不想使用 void,那么您可以声明一个结构,其标签已知但其内容未知,如:

struct foo;

那么你可以使用指向此类结构的指针(例如,你可以定义一个指针struct foo *p;),但编译器将不知道此类结构的大小或内容,因此无法帮助你分配它们,管理它们的数组,或者以其他方式使用它们,而不是通过传递指针和询问外部例程(它们知道内容)。

通常情况下,一个模块中的C例程与另一个模块中的C例程之间的操作:

  • 在一个不知道结构内容的源模块中,您可以使用指针 (struct foo *)。
  • 另一个源模块(通常是某种软件库)会知道结构的内容。它会在自己的源代码中用 struct foo { /* various things */ }; 定义完整的结构,并会在该结构上为第一个模块执行服务。
  • 在两个这样的 C 模块之间,C 标准的规则将定义行为。

由于您在 C 和 Ada 之间进行交互,因此这些交互的规则必须由您的 C 和 Ada 实现提供。

从编写 Ada 绑定到 C 库的角度来看,void* 指定使用什么 Ada Convention-C 访问类型并不重要。除了将它们传递给导入的 C 函数之外,您永远不会对该类型的对象执行任何操作。我一般用

type Void_Ptr is access all Integer;
pragma Convention (C, Void_Ptr);