Project

General

Profile

Task #1490

Updated by Teemu Murtola over 5 years ago

Moved discussion from https://gerrit.gromacs.org/#/c/3384/.

We should decide how we want to use opaque types. Currently, there are quite a few different approaches used, and now and then this gives rise to review comments that would be better discussed through in this general context.

For C code, there are basically three possibilities to declare an opaque type in a header (using naming conventions that seem to be currently used):
# @struct gmx_something_t;@ (a plain forward declaration)
# @typedef struct gmx_something *gmx_something_t;@ (forward declaration of @gmx_something@, plus a typedef for a pointer)
# @typedef struct gmx_something_t gmx_something_t;@ (forward declaration of a struct, and a typedef with the same name).

The first can occur any number of times in different header files, but the latter two can only occur once in a compilation unit.

*Option 1*

Plain use of this option looks like this in any header file that uses the type:
<pre>
struct gmx_something_t;
int gmx_func_using_the_struct(struct gmx_something_t *p, …);
</pre>

Headers do not need to include other headers to get the struct definition, and all headers look the same, but the @struct@ keyword needs to be repeated throughout (in C++, this is no longer necessary, but for C it is).

*Option 2*
The header that declares the type can be like this (assume it is @something.h@):
<pre>
typedef struct gmx_something *gmx_something_t;
int gmx_func_using_the_struct(gmx_something_t p, …);
</pre>

Another header that uses the type can be either like this, introducing an #include dependency:
<pre>
#include "something.h"
int gmx_another_func(gmx_something_t p, …);
</pre>

or like this with a forward declaration, not introducing an #include, but using quite a different syntax:
<pre>
struct gmx_something;
int gmx_another_func(struct gmx_something *p, …);
</pre>

*Option 3*
The header that declares the type can be like this (assume it is @something.h@):
<pre>
typedef struct gmx_something_t gmx_something_t;
int gmx_func_using_the_struct(gmx_something_t *p, …);
</pre>

Another header that uses the type can be like in option 2:
<pre>
#include "something.h"
int gmx_another_func(gmx_something_t *p, …);
</pre>

or like this (as in option 2, but with syntax that is closer to the original header):
<pre>
struct gmx_something_t;
int gmx_another_func(struct gmx_something_t *p, …);
</pre>

*** <hr/>

Options 2 and 3 can also be used such that the typedef is in its own header.

Back