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);
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);