C forward declaration query - c

I have a situation where two of my header files require the data structures defined in either one, i.e. no matter which order you include them it won't compile
however, one of the problem data structures only contains pointers to the data structure declared in the other header file so I would have though that technically it doesn't need to know at this point how big the data structure is so it shouldn't be complaining
A simplified example of what I mean is outlined below. I would have thought that the array of modes in Library doesn't need to know how big a Mode is, only how big a pointer to a Mode is therefore the compiler shouldn't complain if it hasn't yet seen the declaration of Mode in the other header file.
header_1.h
typedef struct
{
Mode **modes;
} Library;
header_2.h
typedef struct
{
int number;
char *name;
} Mode;

It doesn't need to know the size, but it must have seen a declaration. A forward declaration
typedef struct Mode Mode;
before the definition of struct Library suffices.

As currently written, your example does not show the mutual cross-referencing that you mention in the question.
The compiler must be told something about each type it uses. You could use in header_1.h just:
typedef struct Mode Mode;
typedef struct
{
Mode **modes;
} Library;
That would make it compile, at least. The compiler doesn't need the details, but it does need to know that Modes is a type.
Edit:
Note that header_2.h should be modified for this to work. You have to ensure that each typedef appears just once. After you have the typedefs in place, you specify the structure content (definition) once, and you omit the keyword typedef and the typedef name from the structure definition. And you have to decide on exactly the cross-references will be managed. For example, should header_1.h include header_2.h anyway.
I don't remember encountering a case where I really needed mutually referencing structures (in quite a long time programming — long enough that I could have forgotten a example). I do now remember a case of structures mutually referencing each other; it was in a version of make originally written for Minix. I still regard such a requirement as somewhat 'pathological' (or, if you prefer, as a 'code smell') and as something to be avoided whenever possible. If you really must manage it, then the section below explains how I'd go about doing it (and more or less how the make program did go about it).
Mutually-referencing structures
If you truly have two mutually referencing structures, you should (re)consider why you think two headers are better than one. If you still need two headers, you use an idiom like:
header_1.h
#ifndef HEADER_1_H_INCLUDED
#define HEADER_1_H_INCLUDED
#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif
struct Library
{
...
Mode **modes;
...
};
#endif /* HEADER_1_H_INCLUDED */
header_2.h
#ifndef HEADER_2_H_INCLUDED
#define HEADER_2_H_INCLUDED
#ifndef TYPEDEF_MODE
#define TYPEDEF_MODE
typedef struct Mode Mode;
#endif
#ifndef TYPEDEF_LIBRARY
#define TYPEDEF_LIBRARY
typedef struct Library Library;
#endif
struct Mode
{
...
Library **liblist;
...
};
#endif /* HEADER_2_H_INCLUDED */
The repeated typedef 'detection' code is not nice; a single header is better, in my estimation. However, you can include header_1.h and header_2.h above in either order and it should compile.

I believe this is happening because "Mode" is a type defined using typedef and its not the name of the struct. You will either need to explicitly forward declare it or you can try using the code structured as follows:
header_1.h
typedef struct
{
struct _Mode_t **modes;
} Library;
header_2.h
typedef struct _Mode_t
{
int number;
char *name;
} Mode;

Related

Circular dependency between struct and function in C

I have the following files:
A.h
#ifndef __A_H_
#define __A_H_
#include <B.h> // contains foo_t
typedef struct {
foo_t foo;
...
} baz_t;
#endif
B.h
#ifndef __B_H_
#define __B_H_
#include <A.h> // contains baz_t
typedef struct {
...
} foo_t;
extern int useful_func(baz_t d);
#endif
When I compile this B.h refuses to compile complaining error: unknown type name 'baz_t'
I am assuming this error is owing to circular dependency between the two files. But I am wondering how do I forward declare baz_t to solve this? I found answers relating to circular dependencies between structs. But I am unsure how I would solve this. I would appreciate some help here. I am looking for a strictly C99 solution.
EDIT
I previously forgot to mention this but I have already used include guards.
A very obvious solution as suggested by user KamilCuk is moving useful_func to A.h. This has also occured to me but software organization wise useful_func unfortunately belongs to B.h. This problem could be a reflection of a poor design as well.
You can use forward declaration as follows:
struct foo;
typedef struct {
struct foo foo;
...
} baz_t;
And then use it normally on B.h
That said, circular dependencies can be avoided is you define everything on a third header that you use as interface. It would be cleaner, but it's not always possible.
Typically, one would pass pointers to structures rather than passing them by value. If that would be acceptable, things are easy, since C compilers will accept a declaration:
void doSomethingWithAFoo(struct foo *it);
without regard for whether they have seen any definition for struct foo. Indeed, compilers will even accept function definitions like:
void doSomethingWithAFooTwice(struct foo *it)
{
doSomethingWithAFoo(it);
doSomethingWithAFoo(it);
}
without having to know or care about whether, where, or how struct foo is defined.
Note that an advantage of using struct tag syntax rather than typedef names is that prototypes using the struct tag syntax don't require declaring or defining anything that can't be harmlessly redeclared arbitrarily many times.

Using external header file with definitions different from the ones used internally

Suppose you are writing a library that uses internally certain data structures, and wants to export to the user only a subset of them (or hide the exact type using something like void *). The definitions for all the structs and functions used in the library are in a header library.h, which will be used when building the library.
Is it considered good practice to also produce another copy of library.h that would not be used during the build process but only by users linking to the library?
For example suppose the library internally uses the following library.h:
#ifndef LIBRARY_H
#define LIBRARY_H
struct myStruct {
int some_x;
void (*some_callback)(void);
};
typedef struct myStruct *myStruct_t;
#endif
While we would like to hide the definition of myStruct to the user, so we export a header library.h that is:
#ifndef LIBRARY_H
#define LIBRARY_H
typedef void *myStruct_t;
#endif
Is it considered good practice to also produce another copy of library.h that would not be used during the build process but only by users linking to the library?
No. While the details of a best practice for what you want to do are probably a matter of taste, delivering headers not used during building is objectively not a good practice: You risk to introduce typing errors that are never catched when you build your project.
So, without going into details on how you should organize that, what you should definitely do is have each "private" header #include the respective "public" header and not repeat public declarations in the private header. For your example, this would look e.g. like:
library.h:
#ifndef LIBRARY_H
#define LIBRARY_H
typedef struct myStruct *myStruct_t;
// there's absolutely no need to use void * here. An incomplete struct
// type is perfectly fine as long as only pointers to it are used.
#endif
library_internal.h:
#ifndef LIBRARY_INTERNAL_H
#define LIBRARY_INTERNAL_H
#include "library.h"
struct myStruct {
int some_x;
void (*some_callback)(void);
};
#endif
Additional "best practice" notes:
Don't hide pointers behind typedefs. Most C programmers are well aware that a pointer is part of the declarator and expect to explicitly see a pointer when there is one. Dereferencing something that doesn't look like a pointer will just cause confusion for others reading the code. You also might confuse consumers of your library into expecting a myStruct_t to exhibit call-by-value semantics.
Don't define your own types with the _t suffix. At least in POSIX, this is reserved for the implementation (of the compiler/runtime). There's nothing wrong with defining a type of the same name as a struct tag.
Example with these additional suggestions:
library.h:
#ifndef LIBRARY_H
#define LIBRARY_H
typedef struct myStruct myStruct;
#endif
library_internal.h:
#ifndef LIBRARY_INTERNAL_H
#define LIBRARY_INTERNAL_H
#include "library.h"
struct myStruct {
int some_x;
void (*some_callback)(void);
};
#endif
Notice that the C standard doesn't guarantee that a pointer to void has a representation that is compatible with a pointer to a struct! Thus:
typedef struct myStruct *myStruct_t;
typedef void *myStruct_t;
these two are not compatible and cannot be used in a strictly conforming program.
Another thing is that you usually shouldn't hide pointers, unless needed. Consider for example the FILE in the standard library. Its contents are not defined anywhere, but all the functions specifically return a pointer to it and accept a pointer to it.
You can even use a simple struct declaration, instead of definition:
struct myStruct;
Then external users can define a variable as a pointer to it
struct myStruct *handle;
Or if you wish to hide the fact that it indeed is a struct, use a typedef:
typedef struct myStruct myStruct;
Then the users of the external interface can define their variables simply as
myStruct *handle;

How do I typedef an implementation-defined struct in a generic header?

I have a C project that is designed to be portable to various (PC and embedded) platforms.
Application code will use various calls that will have platform-specific implementations, but share a common (generic) API to aid in portability. I'm trying to settle on the most appropriate way to declare the function prototypes and structures.
Here's what I've come up with so far:
main.c:
#include "generic.h"
int main (int argc, char *argv[]) {
int ret;
gen_t *data;
ret = foo(data);
...
}
generic.h: (platform-agnostic include)
typedef struct impl_t gen_t;
int foo (gen_t *data);
impl.h: (platform-specific declaration)
#include "generic.h"
typedef struct impl_t {
/* ... */
} gen_t;
impl.c: (platform-specific implementation)
int foo (gen_t *data) {
...
}
Build:
gcc -c -fPIC -o platform.o impl.c
gcc -o app main.c platform.o
Now, this appears to work... in that it compiles OK. However, I don't usually tag my structures since they're never accessed outside of the typedef'd alias. It's a small nit-pick, but I'm wondering if there's a way to achieve the same effect with anonymous structs?
I'm also asking for posterity, since I searched for a while and the closest answer I found was this: (Link)
In my case, that wouldn't be the right approach, as the application specifically shouldn't ever include the implementation headers directly -- the whole point is to decouple the program from the platform.
I see a couple of other less-than-ideal ways to resolve this, for example:
generic.h:
#ifdef PLATFORM_X
#include "platform_x/impl.h"
#endif
/* or */
int foo (struct impl_t *data);
Neither of these seems particularly appealing, and definitely not my style. While I don't want to swim upstream, I also don't want conflicting style when there might be a nicer way to implement exactly what I had in mind. So I think the typedef solution is on the right track, and it's just the struct tag baggage I'm left with.
Thoughts?
Your current technique is correct. Trying to use an anonymous (untagged) struct defeats what you're trying to do — you'd have to expose the details of definition of the struct everywhere, which means you no longer have an opaque data type.
In a comment, user3629249 said:
The order of the header file inclusions means there is a forward reference to the struct by the generic.h file; that is, before the struct is defined, it is used. It is unlikely this would compile.
This observation is incorrect for the headers shown in the question; it is accurate for the sample main() code (which I hadn't noticed until adding this response).
The key point is that the interface functions shown take or return pointers to the type gen_t, which in turn maps to a struct impl_t pointer. As long as the client code does not need to allocate space for the structure, or dereference a pointer to a structure to access a member of the structure, the client code does not need to know the details of the structure. It is sufficient to have the structure type declared as existing. You could use either of these to declare the existence of struct impl_t:
struct impl_t;
typedef struct impl_t gen_t;
The latter also introduces the alias gen_t for the type struct impl_t. See also Which part of the C standard allows this code to compile? and Does the C standard consider that there are one or two struct uperms entry types in this header?
The original main() program in the question was:
int main (int argc, char *argv[]) {
int ret;
gen_t data;
ret = foo(&data);
…
}
This code cannot be compiled with gen_t as an opaque (non-pointer) type. It would work OK with:
typedef struct impl_t *gen_t;
It would not compile with:
typedef struct impl_t gen_t;
because the compiler must know how big the structure is to allocate the correct space for data, but the compiler cannot know that size by definition of what an opaque type is. (See Is it a good idea to typedef pointers? for typedefing pointers to structures.)
Thus, the main() code should be more like:
#include "generic.h"
int main(int argc, char **argv)
{
gen_t *data = bar(argc, argv);
int ret = foo(data);
...
}
where (for this example) bar() is defined as extern gen_t *bar(int argc, char **argv);, so it returns a pointer to the opaque type gen_t.
Opinion is split over whether it is better to always use struct tagname or to use a typedef for the name. The Linux kernel is one substantial body of code that does not use the typedef mechanism; all structures are explicitly struct tagname. On the other hand, C++ does away with the need for the explicit typedef; writing:
struct impl_t;
in a C++ program means that the name impl_t is now the name of a type. Since opaque structure types require a tag (or you end up using void * for everything, which is bad for a whole legion of reasons, but the primary reason is that you lose all type safety using void *; remember, typedef introduces an alias for an underlying type, not a new distinct type), the way I code in C simulates C++:
typedef struct Generic Generic;
I avoid using the _t suffix on my types because POSIX reserves the _t for the implementation to use* (see also What does a type followed by _t represent?). You may be lucky and get away with it. I've worked on code bases where types like dec_t and loc_t were defined by the code base (which was not part of the implementation — where 'the implementation' means the C compiler and its supporting code, or the C library and its supporting code), and both those types caused pain for decades because some of the systems where the code was ported defined those types, as is the system's prerogative. One of the names I managed to get rid of; the other I didn't. 'Twas painful! If you must use _t (it is a convenient way to indicate that something is a type), I recommend using a distinctive prefix too: pqr_typename_t for some project pqr, for example.
* See the bottom line of the second table in The Name Space in the POSIX standard.

Define a packed version of a C struct

I have a C structure defined somewhere outside my code. Can I define a packed version of the same structure? If I define my own structure from the start, that is easy:
struct test {
// members
} __attribute__((packed));
I defined a simple structure and tried two possibilities, this:
struct test {
int x;
double y;
char z;
};
struct test_p {
struct test __attribute__((packed)) s;
};
and this:
struct test {
int x;
double y;
char z;
};
struct test_p {
struct test p;
} __attribute__((packed));
However, neither of these work (both compile fine though) printing sizeof(struct test_p)=24 on my system (I use gcc 4.8.2 on a 64-bit machine) which is the same as sizeof(struct test). Is there a way to achieve the desired effect?
Just in case you were wondering: I want to parse packets received over network which are just packed structures. The thing is, I can't modify the header file because it is a part of a third-party library, and the structure itself contains too many fields to copy them one by one. I can certainly copy the structure definition to my own header and make the packed version -- actually it is the solution I'm using now -- but I was just wondering if there is a more concise solution which does not involve copying the whole definition.
The gcc has introduced the __attribute__((packed)) precisely to avoid the dangerous effects you are seeking: the definition of the structure should binary compatible between all the user applications and libraries which use the same definition.
But the gcc also provides a way to do the packing the old fashioned, dangerous way - #pragma pack(push,n) and #pragma pack(pop). It would work reliably only if the 3rd party header file contains solely the structure definition, or you do not use anything else from the header. Use them like that:
#pragma pack(push,1)
#include "theheader.h"
#pragma pack(pop)
Otherwise, I personally would have simply copy-pasted the structure definition, renamed it, and added __attribute__((packed)) in my own header. Packing with pragmas the whole header is really a dirty hack. And 3rd party headers might change in unexpected ways, contributing to the bit rot.

compiling on windows and linux

I am new to c, and I have some been given some source code that someone else has written that was compiled on windows.
After trying to make in compile on linux I have errors because linux doesn't support DWORD, WORD, AND UINT32. I have 6 files for example. A.h, A.c, B.h, B.c, C.h, C.c. These keyword are in all the files.
So I am thinking of 2 possible solutions. Which is better #define or typedef.
1)
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned int UNINT32;
2)
#define DWORD unsigned long
#define WORD unsigned short
#define UINT32 unsigned int
For the second part I am wondering where should I put these declarations. Should they go in the header files, or should they go in the source files?
For example should I do something like this in the header files, or in the source files?
#ifdef WIN32
/* windows stuff */
#else
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned int UNINT32;
#endif
Many thanks for the above suggestions,
You have found the solution yourself:
#ifdef WIN32
/* windows stuff */
#else
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned int UNINT32;
#endif
Put this in a separate header file (typedefs.h) and include it from everywhere. Typedef are always preferred over pre-processor macros.
My recommendation: Do not use DWORD, WORD or other Win32 types. I usually prefer to use C99 standard types: uint_t, int_t or uint16_t, uint32_t
Typedefs are definitely nicer. #defines are preprocessor macro's and can have unintended consequences, because basically the C preprocessor performs a global search-and-replace for defines. Typedefs are instructions to the compiler, and much better suited for what you want to do.
typedef would be better in this instance because #define is just a generic mechanism but typedef is for defining types which is what you are doing.
I would say put your code:
#ifdef WIN32
/* windows stuff */
#else
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned int UNINT32;
#endif
into a new header file (with #define guards/#pragma once), then include that from the header or source files as necessary.
Using a typedef turns the result into an actual type that gets put into the syntax tree. (In other words, the compilers knows about it and recognizes it as a part of the language.)
#define, in contrast, is just a text-substitution. So the compiler never gets to know about it, it instead just sees whatever it is that gets substituted. This can make finding compile errors harder.
For your case, I would probably recommend typedef. #define has it's place, but I can't see any reason why you wouldn't want to use typedef here.
Be aware that other libraries may have defined these types, so you may have collisions. If you really want to be cross-platform, you might think about defining types with your app's namespace somehow. Like
myapp_dword
myapp_word
in order to minimize collisions with other libraries.
Finally, I would actually recommend against the entire approach you are taking. If at all possible, it is best to use only the typenames defined in the language and in the C standard library (like size_t, etc.) Your code will be more portable, and you will have less headaches.

Resources