I find a foo.h file having:
typedef STRUCT_s STRUCT;
STRUCT *foo();
and the foo.c file:
#include "i_foo.h"
struct STRUCT_s{
//...
};
#define STRUCT struct STRUCT_s
STRUCT *foo()
{
STRUCT *s;
//...
return s;
}
Is it the common way to hide the structure definition in C ? If yes, I wonder, if the structure is not declared in the header, how is the client supposed to use it?
This is a common way to hide structure definition in C. And client isn't supposed to use structure directly. He has to use only proposed functions from interface to interact with data: instantiate, set or get values, launch operation on it,....
With this way, implementation is totally hidden to client. So client is not constraint by changes in implementation. Library can evolves as it need without disturbing client, according no change in interface.
The user this way cannot instantiate a structure and only sees objects of this type as pointers. Therefore all the constructors and methods, getters, setters etc. are obscure to the user and should be defined in the library source.
One obvious additional consequence is that if you change the structure, the user does not have to change all its uses in the code to initialize new fields or comment out the uses of defunct ones. Since there were none, and there won't be any. The struct's internal private structure is totally hidden.
Yes, this is the common way to declare an abstract data type (ATD). An ADT is used only through its interface which is represented by the functions declared in the header file. A client doesn't access the fields directly. It's also a good idea to add a prefix to all exported identifiers. This avoids name clashes and makes it clear where an imported identifier comes from.
Example:
Stacks.h
typedef struct Stacks_StackDesc *Stacks_Stack;
Stack Stacks_New(void);
void Stacks_Push(int x, Stacks_Stack s);
void Stacks_Pop(Stacks_Stack s, int *top);
Stacks.c
#include "Stacks.h"
struct Stacks_StackDesc {
...
};
Stack Stacks_New(void)
{
...
}
void Stacks_Push(int x, Stacks_Stack s)
{
...
}
void Stacks_Pop(Stacks_Stack s, int *top)
{
...
}
Related
As a learning experience I'm trying to achieve simple class inheritence in C, among other OOP features.
So far I've been able to properly hide "private" functions and attributes of a class from the outer context.
Let's consider Point as a simple class example. It is made up of three modules:
public.h
#ifndef POINT_PUBLIC_H_
#define POINT_PUBLIC_H_
typedef struct Point Point;
Point* newPoint(const int x, const int y);
int getX(const Point* self);
int getY(const Point* self);
void setX(Point* self, const int x);
void setY(Point* self, const int y);
void printPoint(const Point* self);
#endif
This is basically the public interface of Point and it also defines the type Point referring to a struct declared in another module, hiding its attributes.
protected.h
#ifndef POINT_PROTECTED_H_
#define POINT_PROTECTED_H_
struct Point {
int x;
int y;
};
#endif
It hosts the actual struct definition and it could also contain prototypes to functions meant to be accessible only by inhereting classes.
And then there's implementation.c which includes both public.h and protected.h and contains the actual code of public, protected and private functions.
This works great, but what if I wanted to define a Circle class, which extends Point?
I envisioned something like this:
#ifndef CIRCLE_PROTECTED_H_
#define CIRCLE_PROTECTED_H_
#include "../Point/protected.h"
struct Circle {
Point parent;
int radius;
};
#endif
Since the public functions of Point expect a pointer to Point, and since the first attribute of the Circle struct is a Point (not a pointer to it), given a Circle* c object, it becomes possible to do something like getX((Point*) c);.
While this works fine, what I'm not happy about is that I can directly access the attributes to a Point object (including that one in the Circle struct of course) in the Circle modules.
Moving the struct definition to the implementation module would make its attributes completely private, but then I wouldn't be able to directly istantiate a Point object in order to set up the mechanism of inheritence.
Is there a way to make inheritence work while mantaining the privacy of the class that is being extended?
Thanks to #RobertS supports Monica Cellio, I browsed the thread you linked for a little while and it actually gave me an idea.
I tried to actually split the struct in two parts, a protected part which is meant to be visible by the inhereting classes, and a private part which is completely invisible outside of the implementation.c module.
Here's what I did: in implementation.c I defined a new struct which contains all the private attributes:
struct hiddenPoint {
int x;
int y;
};
In protected.h I defined a type referring to this new struct, and I put a pointer to it in the actual Point struct
typedef struct hiddenPoint hiddenPoint;
struct Point {
int aCircleCanSeeThis;
hiddenPoint* hidden;
};
Since hidden is an opaque pointer, even when struct Point is visible some of its attributes can still be made inaccessible. This struct can of course host protected attributes as well, as demonstrated.
This is then my Circle struct:
struct Circle {
Point parent;
hiddenCircle* hidden;
};
It seems to work. Of course it complicates things a tiny bit (now it's p->hidden->x, instead of just p->x), but it does what I was looking for. Don't know if it's a good solution, maybe let me know! Also, if there are other approaches, I'd still like to hear about those :)
I consider my header file to be an interface of my module. I really dislike showing my users things they don't need to see in my interface.
The C folks do that by predeclaring structs and having the functions pass around pointers to that struct.
Which is perfect, except when there is a part of the struct that is public. My users need to be able to access it and modify it freely.
One solution is to do setters and getters and pass a pointer to the struct to which we don't show a definition.
We could also do like the c++ pimpl thing where we would have a pointer to an internal struct in our external struct. Again showing stuff in the interface that we shouldn't be showing.
And then I have an idea. And I want your input. Tell me if you think it's good or bad.
thing.h:
/// Must use thing_init() or bad will happen
struct thing
{
int public_attribute;
};
typedef struct thing thing;
thing*
thing_init();
thing.c:
struct internal
{
int private_attribute;
};
typedef struct internal internal;
thing*
thing_init()
{
void* mem = malloc(sizeof(internal) + sizeof(thing));
internal* i = (internal*)mem;
thing* t = (thing*)(mem + sizeof(internal));
// Initialize stuff
return t;
}
Sooo the idea is like how malloc does things basically. What could go wrong here?
Your approach is broken. For example should the public part have a double and the private part just a char, the arithmetic would cause the the public part to be misaligned.
What you can use and should use is the common initial prefix:
struct thing {
int public_attribute;
};
struct internal {
struct thing public;
int private_attribute;
};
struct thing *thing_init()
{
struct internal *mem = malloc(sizeof(struct internal));
internal->public->public_attribute = 6 * 9;
internal->private_attribute = 42;
return &interal->public;
// or
return (struct thing *)internal;
}
I.e. the public part is the first member of the entire structure. This technique is well-defined in C.
Then in all functions that get in struct thing * you cast this pointer to struct internal *, and are ready to use the public and private members.
This technique is used e.g. by the CPython interpreter, where all Python objects in C code share a common initial sequence of PyObject followed by private parts.
I want a process to expose a structure of a message, so it can be used by other processes receiving it.
However, this structure includes types of arguments which are defined in other header files, which themselves include a bunch of other header files.
typedef struct sfp_info_s {
int port;
char platform_id[50];
sff_eeprom_t sff_type;
char status_str[50];
sff_dom_t sff_dom;
}sfp_info_t;
sff_eeprom_t is defined in a header file named : sff_db.h
and this file itself includes other files :
#ifndef __SFF_SFF_H__
#define __SFF_SFF_H__
#include <sff/sff_config.h>
#include <AIM/aim_pvs.h>
#include <dependmodules.x>
What is the best way to create this API without the mess of including all these files in all the processes which need to know only the structure of the message?
The C standard allows a pointer to a struct to be converted to a pointer to its first member and back. So you can package the members you want to expose into a struct and publish that in a public header:
typedef struct
{
int port;
char platform_id[50];
} sfp_public_t;
In a private header, you would have:
typedef struct
{
sfp_public_t public;
sff_eeprom_t sff_type;
char status_str[50];
sff_dom_t sff_dom;
} sfp_info_t;
Given a pointer p to an sfp_info_t, you may convert it to a pointer to an sfp_public_t and pass it to other code. When you receive such a pointer from other code, you may convert it to a pointer to an sfp_info_t.
The other code will of course not know the true size of the object, so it cannot allocate new instances. Your API will need to provide supporting routines to allocate such objects.
A drawback is this requires you access the packaged members using p->public.name instead of p->name inside your code, although the code that receives the converted pointer can simply use p->name. I think you may be able to avoid that by using an anonymous struct member inside sfp_info_t. But an anonymous struct cannot be declared with a tag or a typename, so you need to repeat the declaration:
typedef struct
{
struct
{
int port;
char platform_id[50];
};
sff_eeprom_t sff_type;
char status_str[50];
sff_dom_t sff_dom;
} sfp_info_t;
If I have a source file mystruct.c and a corresponding header file, what is the proper way to define it in each file?
assume I have a structure:
typedef struct my_struct {
int a;
} MyStruct;
should it be placed like this in the header? or should it look more like this:
source file:
struct my_struct {
int a;
};
header file:
typedef struct my_struct MyStruct;
I have the same question about enums and unions.
Im basically looking for the standard way of defining these things so that they can be used in many other files without having to worry about redefinition errors.
Defining the contents of your struct in the .c file and just declaring the struct to exist in the header means that you need to provide a function to create the struct, e.g.
rc = my_struct_create(&s);
It has the advantage that you can change the contents of your struct without having to recompile dependent code - this is because the struct is opaque, the only way to create it is with your function and the only way to access any members of the struct will be through functions you define.
I'd personally recommend that approach for library code. Otherwise it really depends on what you're trying to achieve.
In the .h file, you would put the structure definition, and the function prototypes:
point.h
typedef struct {
int x, y;
} point;
point *initpt(int, int);
In the .c file, you would implement the functions:
point.c
point *initpt(int x, int y)
{
point *p;
p->x = x;
p->y = y;
return p;
}
It depends if the structure members are part of the public API or not. If the users of the API are not supposed to access the structure members, leave the structure definition to the .c file only. If they are supposed to know the implementation of the structure (for example because you want to allow them to access the members of the structure) put the structure definition in the .h. By principle be more restrictive first, and then if you have too, you can still change it later.
I am currently working on an embedded system and I have a component on a board which appears two times. I would like to have one .c and one .h file for the component.
I have the following code:
typedef struct {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
} ads1248_options_t;
Those are all hardware settings. I create two instances of this struct (one for each part).
Now I need to keep an array of values in the background. E.g. I can read values from that device every second and I want to keep the last 100 values. I would like this data to be non-accessible from the "outside" of my component (only through special functions in my component).
I am unsure on how to proceed here. Do I really need to make the array part of my struct? What I thought of would be to do the following:
int32_t *adc_values; // <-- Add this to struct
int32_t *adc_value_buffer = malloc(sizeof(int32_t) * 100); // <-- Call in initialize function, this will never be freed on purpose
Yet, I will then be able to access my int32_t pointer from everywhere in my code (also from outside my component) which I do not like.
Is this the only way to do it? Do you know of a better way?
Thanks.
For the specific case of writing hardware drivers for a microcontroller, which this appears to be, please consider doing like this.
Otherwise, use opaque/incomplete type. You'd be surprised to learn how shockingly few C programmers there are who know how to actually implement 100% private encapsulation of custom types. This is why there's some persistent myth about C lacking the OO feature known as private encapsulation. This myth originates from lack of C knowledge and nothing else.
This is how it goes:
ads1248.h
typedef struct ads1248_options_t ads1248_options_t; // incomplete/opaque type
ads1248_options_t* ads1248_init (parameters); // a "constructor"
void ads1248_destroy (ads1248_options_t* ads); // a "destructor"
ads1248.c
#include "ads1248.h"
struct ads1248_options_t {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
};
ads1248_options_t* ads1248_init (parameters)
{
ads1248_options_t* ads = malloc(sizeof(ads1248_options_t));
// do things with ads based on parameters
return ads;
}
void ads1248_destroy (ads1248_options_t* ads)
{
free(ads);
}
main.c
#include "ads1248.h"
int main()
{
ads1248_options_t* ads = ads1248_init(parameters);
...
ads1248_destroy(ads);
}
Now the code in main cannot access any of the struct members, all members are 100% private. It can only create a pointer to a struct object, not an instance of it. Works exactly like abstract base classes in C++, if you are familiar with that. The only difference is that you'll have to call the init/destroy functions manually, rather than using true constructors/destructors.
It's common that structures in C are defined completely in the header, although they're totally opaque (FILE, for example), or only have some of their fields specified in the documentation.
C lacks private to prevent accidental access, but I consider this a minor problem: If a field isn't mentioned in the spec, why should someone try to access it? Have you ever accidentally accessed a member of a FILE? (It's probably better not to do things like having a published member foo and a non-published fooo which can easily be accessed by a small typo.) Some use conventions like giving them "unusual" names, for example, having a trailing underscore on private members.
Another way is the PIMPL idiom: Forward-declare the structure as an incomplete type and provide the complete declaration in the implementation file only. This may complicate debugging, and may have performance penalties due to less possibilities for inlining and an additional indirection, though this may be solvable with link-time optimization. A combination of both is also possible, declaring the public fields in the header along with a pointer to an incomplete structure type holding the private fields.
I would like this data to be non-accessible from the "outside" of my
component (only through special functions in my component).
You can do it in this way (a big malloc including the data):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct {
uint32_t pin_reset;
uint32_t pin_drdy;
uint32_t pin_start;
volatile avr32_spi_t *spi_module;
uint8_t cs_id;
} ads1248_options_t;
void fn(ads1248_options_t *x)
{
int32_t *values = (int32_t *)(x + 1);
/* values are not accesible via a member of the struct */
values[0] = 10;
printf("%d\n", values[0]);
}
int main(void)
{
ads1248_options_t *x = malloc(sizeof(*x) + (sizeof(int32_t) * 100));
fn(x);
free(x);
return 0;
}
You could make a portion of your structure private like this.
object.h
struct object_public {
uint32_t public_item1;
uint32_t public_item2;
};
object.c
struct object {
struct object_public public;
uint32_t private_item1;
uint32_t *private_ptr;
}
A pointer to an object can be cast to a pointer to object_public because object_public is the first item in struct object. So the code outside of object.c will reference the object through a pointer to object_public. While the code within object.c references the object through a pointer to object. Only the code within object.c will know about the private members.
The program should not define or allocate an instance object_public because that instance won't have the private stuff appended to it.
The technique of including a struct as the first item in another struct is really a way for implementing single inheritance in C. I don't recall ever using it like this for encapsulation. But I thought I would throw the idea out there.
You can:
Make your whole ads1248_options_t an opaque type (as already discussed in other answers)
Make just the adc_values member an opaque type, like:
// in the header(.h)
typedef struct adc_values adc_values_t;
// in the code (.c)
struct adc_values {
int32_t *values;
};
Have a static array of array of values "parallel" to your ads1248_options_t and provide functions to access them. Like:
// in the header (.h)
int32_t get_adc_value(int id, int value_idx);
// in the code (.c)
static int32_t values[MAX_ADS][MAX_VALUES];
// or
static int32_t *values[MAX_ADS]; // malloc()-ate members somewhere
int32_t get_adc_value(int id, int value_idx) {
return values[id][value_idx]
}
If the user doesn't know the index to use, keep an index (id) in your ads1248_options_t.
Instead of a static array, you may provide some other way of allocating the value arrays "in parallel", but, again, need a way to identify which array belongs to which ADC, where its id is the simplest solution.