Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

Does this mean that the following is illegal?

struct C { };

Or what does it mean?

I used a Convention=>C Ada pointer to an empty struct (in fact empty Ada record) to serve instead void* in my bindings of a C library (because there is no void* in Ada). I wonder if this is incorrect.

What do I misunderstand?


See also "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." at https://dlang.org/spec/struct.html

like image 934
porton Avatar asked Mar 04 '23 20:03

porton


1 Answers

Very little in C is illegal, meaning you cannot do it. Rather, many things are not defined by the C standard, meaning that, if you do them, the C standard does not say what will happen. Structures with no named members are such a thing.

C 2018 6.7.2.1 8 says, in part:

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.

If you need something to serve as an “unknown type” and do not want to use void, then you can declare a structure whose tag is known but whose contents are not, as with:

struct foo;

Then you can use pointers to such structures (for example, you can define a pointer struct foo *p;), but the compiler will not know the size or contents of such structures, so it cannot help you allocate them, manage arrays of them, or otherwise use them other than by passing pointers around and asking external routines (which do know about the contents).

Normally, in operations between C routines in one module and C routines in another module:

  • In one source module that did not know about the contents of the structure, you would use a pointer (struct foo *).
  • Another source module (often a software library of some sort) would know about the contents of the structure. It would, inside its own source code, define the full structure with struct foo { /* various things */ };, and it would perform services on this structure for the first module.
  • Between two such C modules, the rules of the C standard would define the behavior.

Since you are interfacing between C and Ada, the rules for those interactions must be provided by your C and Ada implementations.

like image 142
Eric Postpischil Avatar answered Mar 15 '23 18:03

Eric Postpischil