INHERITANCE LIBRARY - c

I'm interested about this. I have a library house.h, which includes a library roof.h. Also I have a library car.h, which includes a library roof.h.
Library roof.h contains next includes (so far written only using as a relief to explain), e.g.:
//this is only for the house.h`
include tile.h
include beam.h
include form_roof_house.h
//this is only for the car.h
include sheet_metal.h
include form_roof_car.h
include modular.h //, etc.
Now, my questions is, whether there is a way that my library roof.h knows which library is included here, respectively that my library roof.h knows that library house.h is included here. Thanks!

Header files should include header guards ie they will not be included twice. You're alluding to two roof.h files? If they share the same guards the first one will be loaded. C the language without the preprocessor has no knowledge of what's happening as files are included etc before their compiled.

Your program design is flawed, because roof needs to be an "abstract base class" that only know about generic roof stuff and that presents an API. Therefore, roof.h should not include any of those headers. Most importantly there should not be a tight coupling between house roof and car roof, that doesn't make any sense, and those two might not even exist in the same program.
Instead, you need to make two new classes that inherit roof, call them for example roof_house and roof_car. Each of them is including roof.h.
From there, you can implement the program design in many ways, depending on how picky you want to be with the OO part of the design. There's not even a need to use OO design (C programmers are often scared about it) but the above mentioned file dependencies must hold.
Avoiding tight coupling is not specific to OO, it is about applying common sense: avoiding fail-cascading bugs, avoiding maintenance problems etc etc.
One possible design is to implement polymorphism through function pointers:
roof.h
typedef struct roof_t roof_t; // forward declaration
typedef void roof_func_t (const roof_t* roof);
typedef struct
{
roof_func_t* init;
roof_func_t* draw;
} roof_t;
// functions for public interface:
roof_t* roof_create (const roof_func_t* init, const roof_func_t* draw);
void roof_draw (const roof_t* roof);
roof.c
#include "roof.h"
roof_t* roof_create (const roof_func_t* init, const roof_func_t* draw)
{
roof_t* roof = malloc(sizeof(roof_t));
roof->init = init;
roof->draw = draw;
return roof;
}
void roof_draw (const roof_t* roof)
{
roof->draw();
}
roof_house.h
#include "roof.h"
void roof_house_init (const roof_t* roof);
void roof_house_draw (const roof_t* roof);
roof_house.c
#include "roof_house.h"
void roof_house_init (const roof_t* roof)
{
// whatever needs to go here
}
void roof_house_draw (const roof_t* roof)
{
// whatever needs to go here
}
main.c
#include "roof.h"
#include "roof_house.h"
roof_t* my_roof = roof_create(roof_house_init, roof_house_draw);
roof_draw(my_roof);
This is of course just a rough example. Private encapsulation etc needs to be implemented and there might be need for a way for the inherited classes to add their own member variables etc.
Needless to say, each header file should always have header guards.

Related

How to share opaque type across multiple translation units?

I'm working on my own C-project and need some design/common_C_idiom advice. The problem I'm trying to solve is to open an input date stream of a configured device. But I want to keep configuration and device separated. Here is what I tried:
Configuration:
config.h
#ifndef CONFIG_H
#define CONFIG_H
typedef struct config_t config_t;
config_t* config_t_allocate(void);
void config_t_free(config_t *);
//functions to set configuration parameters
#endif //CONFIG_H
config.c
#include <stdlib.h>
#include "device.h"
struct config_t{
const char * name;
};
config_t* config_t_allocate(void){
return malloc(sizeof(config_t));
}
void config_t_free(config_t * config_ptr){
free(config_ptr);
}
Device:
device.h
#ifndef DEVICE_H
#define DEVICE_H
typedef struct config_t config_t;
typedef struct device_t device_t;
void configure_device(device_t**, config_t*);
//other device-related methods
#endif //DEVICE_H
device.c
#include "device.h"
#include <sys/fcntl.h>
struct device_t{
int fd;
};
//Does not compile. What is the confit_t type?
void configure_device(device_t** device, config_t* config_ptr){
*device = malloc(sizeof(**device));
(*device) -> fd = open(config_ptr -> name, O_RDONLY);
}
So I would like to share the config_t type completed in config.c across multiple translation units. The only thing I can imagine is to create a "private" header file containg the struct. Something like this:
types/configdef.h
#ifndef TYPES_CONFIG_DEF_H
#define TYPES_CONFIG_DEF_H
struct config_t{
const char * name;
};
#endif //TYPES_CONFIG_DEF_H
And include it everywhere I need the config_t.
If you use an opaque type like config_t, you forgo the option of accessing its members directly in the source code that isn't privy to the implementation details. You could provide a function to do that, though:
extern const char *config_t_get_name(config_t *config);
or thereabouts, declared in config.h, defined in config.c, used in device.c.
But how about putting struct config_t{ const char * name; }; into some header file which I will not expose (sort of library private) and using it everywhere in implementation C files. Isn't it common or does it have some drawbacks?
The primary alternative to access functions is, indeed, a 'private' header, but that's usually not as good as access functions. It can be done; it is not entirely uncommon, especially if the suite of functions that need access to the internals of the structure is too large to fit sanely in a single source file (or because local rules are 'one non-static function per source file', or …). The difficulty, then, is ensuring that files that should not be privy to the private header cannot (do not) use it. That suggests that the private header should not be installed with the library, and possibly the private header should be in a separate directory from the public header(s) for the project.
Consider whether you should enforce:
#include "project/headerX.h" // General, public headers for the project
#include "project/private/internal.h" // Private headers for limited use
You can then police the use of the private headers by using grep or equivalent to find references that should not be allowed, etc. Alternatively, or perhaps in conjunction, use a distinctive naming scheme for private headers, using the pvt_ prefix to denote 'private':
#include "project/internal/pvt_config.h"
There are endless variations on the theme. Programmers will devise all sorts of schemes to gain access to private headers to make use of them. Ultimately, you have to trust your programmers to obey the rules — thou shalt not use private headers except in files explicitly granted permission to use them. If they cannot accept that discipline, maybe they shouldn't be on the project after all. Or maybe you should take time to understand why the recalcitrant programmers cannot use the access functions you provide — is there something wrong with the design?
You might search on Google (or your search engine of choice) for 'getters setters'; the results seem to be informative. Add your language of choice (C++, Java, JavaScript figure prominently; C not so prominently but it does pull up references that would probably be helpful).

Implementing data hiding access specifiers in C language

Is there is a way to implement access specifiers like "private", "protected" in C language. I came across solutions in the internet about using "static" and "ifdefs" for making a function available only inside certain other functions.
Apart from these, is there any C implementation equivalent of using private and protected access specifiers in C++ classes?
C does not have access specifiers. The only way to hide something from your callers is to not provide its declaration in the header.
You can make it static in the translation unit:
myapi.h
extern int visibleVariable;
void visibleFunction();
myapi.c
int visibleVariable;
static int invisibleVariable;
void visibleFunction() {
...
}
static void invisibleFunction() {
...
}
You can also hide the definition of a struct by placing it in the implementation file. This way all fields of your struct would be private to the translation unit. The drawback to this approach is that the users of your API would be unable to declare variables of your struct's type, so they would need to deal with your struct through pointers.
C has no concept of inheritance, hence there is no equivalent of protected access.
C does not have user definable name spaces or access specifiers. Since you exclude (ab)use of preprocessor, the only way to get compiler error trying to access private parts of "classes" is to not have a .h file which exposes "private" stuff. They can still be put into "private" separate .h files (included by module's or library's own .c files, but not meant to be included from application code), or hidden behind #ifdefs (requiring special define to activate the "private" parts).
One common way to hide things is to use opaque structs AKA opaque pointers. For that approach, the code outside a module or library only has pointer to a struct, but no struct definition. And then it uses functions offered by the module to get an instance, access it, and finally release it.
With this approach, you easily get public interface: the functions you provide in the public .h file, as well as any public support structs which have definition there. The private interface is the code where the full struct definition is visible, and any functions which are not in the public .h file.
Protected access implies inheritance, which usually works very differently from C++, when implemented with C by hand, and which is too broad a subject to cover in this answer. The closest thing to this would probably be to have several .h files, which provide several levels of "public" access, and then it is responsibility of the programmer to not get into problems with them.
The good thing about this approach is, other code using the module does not need to be modified (or even recompiled), if struct is changed. Often struct might even be an union, and then the module's functions would branch based on the actual type, all invisibe from the code using it. Another good thing is, the module can control creation of structs, so it could for example have a pool of structs and avoid using heap, all invisible to the application code. One downside is, you can't have inline functions (because the inline function body in .h file would need the struct definition, which we are trying to hide here), which prevents some nice compiler optimizations in cases where performance is a concern.
Example (untested code written for this answer):
module.h:
// ...other standard header file stuff ...
// forward declaration of struct
struct module_data;
// "constructor" function
struct module_data *module_initialize_data(int value);
// modification function
int module_update_data(struct module_data *data, int adjust);
// "destructor" function
void module_release(struct module_data *data);
module.c
#include "module.h"
// struct definition only in the .c file
struct module_data {
int value;
};
struct module_data *module_initialize_data(int value) {
struct module_data *data = malloc(sizeof(*data));
data->value = value;
return data;
}
int module_update_data(struct module_data *data, int adjust) {
data->value += adjust;
return data->value;
}
void module_release(struct module_data *data) {
free(data);
}
Relevant Wikipedia links for reference:
https://en.wikipedia.org/wiki/Opaque_pointer
https://en.wikipedia.org/wiki/Opaque_data_type

Interface/Implementation in ANSI C

I'm working on a large project in C, and I want to organize it using interface (.h) and implementation (.c) files, similar to many object-oriented languages such as Objective-C or Java. I am familiar with creating static libraries in C, but I think that doing so for my project is unnecessarily complex. How can I implement an interface/implementation paradigm in ANSI C? I'm primarily using GCC for compilation, but I'm aiming for strict adherence to ANSI C and cross-compiler compatibility. Thanks!
It sounds like you are already doing the right thing: good C code also organizes interfaces in .h-files and implementations in .c-files.
Example a.h file:
void f(int a);
Example a.c file:
#include "a.h"
static void helper(void) {...}
void f(int a) {... use helper()...}
Example main.c file:
#include "a.h"
int main(void) { f(123); return 0; }
You get modularity because helper-functions are not declared in headers so other modules dont know about them (you can declare them at the top of the .c file if you want). Having this modularity reduces the number of recompiles needed and reduces how much has to be recompiled. (The linking has to be done every time though). Note that if you are not declaring helper-functions in the header then you are already pretty safe, however having the static in front of them also hides them from other modules during linking so there is no conflict if multiple modules use the same helper-function-names.
If you are working with only primitive types then that is all you need to know and you can stop reading here. However if your module needs to work with a struct then it gets just a little more complicated.
Problematic example header b.h:
typedef struct Obj {
int data;
}*Obj;
Obj make(void);
void work(Obj o);
Your module wants to pass objects in and out. The problem here is, that internals are leaked to other modules that depend on this header. If the representation is changed to float data then all using modules have to recompile. One way to fix this is to only use void*. That is how many programs do it. However that is cumbersome because every function getting the void* as argument has to cast it to Obj. Another way is to do this:
Header c.h:
typedef struct Obj*Obj;
Obj make(void);
void work(Obj);
Implementation c.c:
#include "c.h"
typedef struct Obj {
int data;
}*Obj;
The reason why this works is, that Obj is a pointer (as opposed to a struct by value/copy). Other modules that depend on this module only need to know that a pointer is being passed in and out, not what it points to.
You must read something about OOP with non OOL such like http://www.cs.rit.edu/~ats/books/ooc.pdf.
But, doing such you will never have strong OOP typing.
Please do yourself a favor and read C Interfaces and Implementations: Techniques for Creating Reusable Software
Here is a repository of mine that holds some libs written in C using the pattern of interfaces & implementation described in the book.

Design issue in C

I'm struggling with a design issue, and I'm trying to find the "Best Practice" answer for my situation.
Say I have a file called Logger.c (And Logger.h) that is responsible for logging actions in my program.
I want logger to be referenced by all my modules, so each module's has a
#include Logger.h.
Say I have a module called NTFS.c that is responsible for interaction with the NTFS FS, This module has special structs that are defined in its header, for example: NTFS_Partition.
Here is the problem:
On one hand, I want logger to be able to print to a log file a formatted representation of NTFS_Partition, and by that I must #include NTFS.h in Logger.h.
(Inside Logger.h)
#include NTFS_Partition
VOID Log_Partition(NTFS_Partition *part);
On the other hand, I am not sure Logger should re-reference modules that reference him.
Currently I'm seeing a two main choices:
1.Logger.h includes NTFS.h, and NTFS.c include Logger.h (This works)
2.I create a new header file called NTFS_Types.h that would be shared accross all the
modules, and would only contain the deceleration of NTFS structs (like NTFS_Partition).
Thanks a lot,
Michael.
You can create a shared header where all your structs are defined.
// structs.h
struct NTFS_Partition { .. };
struct FAT32_Partition { .. };
struct FAT16_Partition { .. };
Include it in logger.h.
// logger.h
#include "structs.h"
VOID Log_Partition(NTFS_Partition *part);
VOID Log_Partition(FAT32_Partition *part);
VOID Log_Partition(FAT16_Partition *part);
And include the logger.h in various source files.
// NTFS.c
#include "logger.h"
// FAT32.c
#include "logger.h"
// FAT16.c
#include "logger.h"
In C++, it's better to keep different irrelevant class definitions in different header files. But in C, placing different struct definitions in separate headers is probably an overkill.
It isn't entirely clear whether you are coding in C or C++; I'm going to assume C (so no overloaded function names, etc). It seems to me that you need to 'forward declare' your structures. In Logger.h, you write:
#ifndef LOGGER_H_INCLUDED
#define LOGGER_H_INCLUDED
struct NTFS_Partition; // No details - just the name (3 times)
struct FAT16_Partition;
struct FAT32_Partition;
...
void Log_NTFS_Partition(struct NTFS_Partition *part);
void Log_FAT16_Partition(struct FAT16_Partition *part);
void Log_FAT32_Partition(struct FAT32_Partition *part);
#endif // LOGGER_H_INCLUDED
This is all the information that a general client (of Logger.h) needs to know.
If a specific client is dealing with NTFS partitions, then it will not only include Logger.h but also NTFS.h, which will provide the full definition of struct NTFS_Partition { ... };, so the client can create instances of the structure and populate it with data. The code that implements the logging, Logger.c, will also include Logger.h and NTFS.h (and FAT16.h and FAT32.h), of course, so that it too can reference the members of the structures.
The header for a service (such as Logger.h) should provide the minimal amount of information that the clients of the service need for compilation. The implementation file may need more information, but can collect the extra information from headers that provide it.
One advantage of using the struct tag notation is precisely that it can be repeated as often as necessary without messing anything up. If you don't have C11, you can't repeat a typedef, so if you write:
typedef struct NTFS_Partition NTFS_Partition;
you must only include that line once. The difficulty is making sure that it is only defined once. For that, you probably use a header such as FSTypes.h to define the file-system typedefs that is properly protected by header guards and is included in any file that needs any of the typedefs. You can then reference the types without the preceding struct keyword.
If you code in C++, the typedef isn't necessary; struct NTFS_Partition; declares that there is such a structure type and also declares NTFS_Partition as a name for that type. If your code is bilingual, use the typedef version; it works in both C and C++.
Note that if your functions such as Log_NTFS_Partition() take an actual structure instead of a pointer to a structure, then you have to have the definition of the structure in scope. If the functions only take pointers, though, a forward declaration is sufficient.

Generic / OO-like programming in C while avoiding symbol clashes

I'm making a little game in C. I try to program in an object-oriented manner using function pointers.
I really wanted to push ahead this time and not overdo making things too generic, I often get lost in this. Using plain old C has helped me a lot in programming faster and better.
Currently, I describe "Game states" using:
/* macros */
#define SETUP_ROUTINE(component) component##_##setup_routine
#define DRAW_ROUTINE(component) component##_##draw_routine
#define EVENT_ROUTINE(component) component##_##event_routine
#define UPDATE_ROUTINE(component) component##_##update_routine
#define TEARDOWN_ROUTINE(component) component##_##teardown_routine
#define SETUP_ROUTINE_SIGNATURE void
#define DRAW_ROUTINE_SIGNATURE void
#define EVENT_ROUTINE_SIGNATURE SDL_Event evt, int * quit
#define UPDATE_ROUTINE_SIGNATURE double t, float dt
#define TEARDOWN_ROUTINE_SIGNATURE void
/* data */
typedef enum GameStateType {
GAME_STATE_MENU,
GAME_STATE_LEVELSELECT,
...
} GameStateType;
typedef struct GameState {
GameStateType state;
GameStateType nextState;
GameStateType prevState;
void (*setup_routine)(SETUP_ROUTINE_SIGNATURE);
void (*draw_routine)(DRAW_ROUTINE_SIGNATURE);
void (*event_routine)(EVENT_ROUTINE_SIGNATURE);
void (*update_routine)(UPDATE_ROUTINE_SIGNATURE);
void (*teardown_routine)(TEARDOWN_ROUTINE_SIGNATURE);
} GameState;
While you may or may not appreciate this style, I have grown to like it and it serves me well so far on this small (private..) project.
I for instance have a "transition" game state that simply transitions from one game state to the other.
However, when I link the different game states together, I get ugly things like:
extern GameState GAME; /* The 'singleton' "game" */
extern void menu_setup_routine(SETUP_ROUTINE_SIGNATURE);
extern void menu_draw_routine(DRAW_ROUTINE_SIGNATURE);
extern void menu_event_routine(EVENT_ROUTINE_SIGNATURE);
extern void menu_update_routine(UPDATE_ROUTINE_SIGNATURE);
extern void menu_teardown_routine(TEARDOWN_ROUTINE_SIGNATURE);
extern void debug_setup_routine(SETUP_ROUTINE_SIGNATURE);
extern void debug_draw_routine(DRAW_ROUTINE_SIGNATURE);
extern void debug_event_routine(EVENT_ROUTINE_SIGNATURE);
extern void debug_update_routine(UPDATE_ROUTINE_SIGNATURE);
extern void debug_teardown_routine(TEARDOWN_ROUTINE_SIGNATURE);
Also, for each game state I have things like:
menu.c
struct MenuModel menu_model; /* The singleton 'menu' model */
game.c
struct GameModel game_model; /* The singleton 'game' model */
..which are global pieces of data that remain on the heap throughout the execution of the program. Of course the fields of these usually consist of pointers to dynamic memory, which and which contents' change as the game states change.
While at first I thought this was insane I started to like it. However it may cause namespace conflicts when another .o is linked that also has such a "menu_model" symbol.
First question: is this insane, is there a better way of doing things like this? What do people usually do to avoid these possible symbol name conflicts?
Second question is that I have to republish the different ..._setup_routine/..draw_routine/.. functions using "extern.." in the one source file/object file that holds the following types of functions:
void (*get_setup_routine(GameStateType state))(SETUP_ROUTINE_SIGNATURE) {
switch(state) {
case GAME_STATE_MENU:
return SETUP_ROUTINE(menu);
break;
case GAME_STATE_LEVELSELECT:
return SETUP_ROUTINE(level_select);
break;
default: /* ... */ break;
}
}
Because otherwise when compiling it does not know the symbol "menu_setup_routine".
Anyway, any advise is welcome, I'm a bit new to C and although I really like programming in it, I wonder if I'm using it right in this case.
Some non-small games use similar paradigm. The first example which pops into my mind is Neverball.
You might want to download its source code (its an OpenSource game) and see how they're doing.
Personally I think you should check C++. I used to use C only, also in the way you're doing, up to a some years ago; then I went crazy (mostly because of name clashes), and switching to C++ made me discover a new world. Anyway I understand you could want to avoid it for a number of reasons.
About objecst like your menu_model, whose name clashes with other menu_model in other C source files, you should just declare them as static:
static struct MenuModel menu_model; /* The singleton 'menu' model */
That menu_model will be visible in the C source file it's declared in (you won't be able to use it in other C source files, not even by externing it), and its name won't clash with other static variables with the same name declared in other C source files.
About the second issue there's not much to do. Functions and variables you use must be declared.
I'm a bit confused, but I don't think you should need all those menu_setup_routine and so on to have external linkage. Instead, define a struct game_vtable containing one function pointer for each routine, and then let each of "menu" and "debug" provide access to an instance of that struct. To call a function on a component, you do something like:
// vtable is a global symbol
component##_##vtable.setup
or
// vtable is acquired from a function
component##_##getvtableptr()->setup
or you can pass vtable pointers around as parameters, in place of your GameStateType, and maybe thereby get rid of some of your switch statements.
As for the globals - you don't provide a lot of detail, but the way to avoid a global Menu is to create one locally, at a high level, and then pass it around to anyone that needs it. If you decide that you prefer the global, you have to give it a unique name if it's going to be visible outside its TU.

Resources