Incomplete type with size - c

I'm writing a C library, and have a struct that looks (roughly) like:
struct Obj {
char tag,
union {
int i,
void *v
} val
};
I do not want to expose the internals of this struct through the API, because users do not need to know the implementation and they could change in future versions. Users can interact with the struct via functions in the API.
I used incomplete types in the header for other, larger types in my API, which can only be accessed via pointer by the user. I do not want to restrict users to accessing Obj via pointer, as Obj will likely only be 16 bytes maximum.
I have not been able to use an incomplete type here, because I do not know of a way to expose only the size of the struct to users, without fields.
My question is:
Is there a way to expose a type with size only in C (no knowledge of the fields in the struct given to user), some other hack to accomplish what I want, or should I implement this in some completely different way?
Please comment if I haven't provided enough details or anything is unclear.

The standard pattern for this is to create a function which allocates the struct for the user:
struct Obj* obj_new(void) {
return malloc(sizeof(struct Obj));
}
Then just leave the type as incomplete in your public header.
Of course, if you really want to expose only the size, you could just create a function which returns sizeof(struct Obj). Obviously people can misuse it (e.g., hardcoding the value into their code as an "optimization" to avoid calling that function), but that's not on you. It is something that is done occasionally, usually to help facilitate inheritance.

Related

static linked list in C that holds any data type but all of the same type

I'm trying to implement a static linked list in C that holds any data type. I know that the node struct should use a void* but I also want each list to hold the same data type. That is, lists can hold any data type but every item in the list must be of the same type. I know using void* allows nodes to have any data type but how do I make it so that a list only contains items of the same type?
You can use the macro system to handle non void * lists... if you do something like:
#define LIST_OF(_type) struct node_of_##_type { \
struct node_of_##_type *prev, *next; \
_type data; \
}
then, you can declare as many list types as you want, you have only to say something like:
typedef char *string;
LIST_OF(string) *my_list = NULL;
/* will expend to something similar to:
struct node_of_string {
struct node_of_string *prev, next;
string data;
} *my_list = NULL;
*/
This is an attempt (well, too far yet to be comparable) to emulate the templates of C++. You will not have a list capable of storing anything, but a list adapted only to one type (but any type that can be typedef'd, as the type parameter must be a typename, not a type specification. And, as in C++, once you have that you have to instantiate every function using that type, to the proper type, forcing you to name it, (as functions cannot be overloaded in C) and to rewrite (by means of more macro expansions) to the actual code. Things get complicate soon, making it necessary some help from the language to use OOP techniques in C.
The problem with C is that it is a weakly typed language, this means that you can cast a Banana to a Truck and the compiler will be totally fine with that. Programmers in C are conditioned to keep this in mind and be very wary of what they are doing, that is to say it is the programmers responsibility to "think ahead" and make no such mistakes (e.g. like putting a Banana in a list of Trucks). You could work around this by adding another layer between your datatypes and the list nodes. A trust could hold a void* to the actual type together with an enum or an integer value representing the id of the data type you are trying to store in the list, you could call this a tagged node or something. The issue now becomes how to retrieve that tag or enum value. This will sadly add some boilerplate to your program, however, this might be automated using macro's.
Note that the problem you are highlighting (weak typing) is just part of the quirkiness of C. what I usually do in these situations is naming the variable holding the list accordingly and think very carefully of what I am doing with this variable.
A solution may be to, instead of using a List, use an array, this will at least produce a segmentation fault in some scenario's, but that will also be the case if you cast a Truck to a Banana and try to access fields which are out of memory range...
Hope this helps!

Does C have a version of JavaScript "this"?

I've use quite a bit of JavaScript so far. If you were to use an object constructor in JavaScript, you have access to the this constructor.
So my question relates to trying to use a similar concept in C. I created a struct that I want to be able to self reference:
struct Storage {
void (*delete)();
}
So if I were to allocate a Storage class:
struct Storage *myStruct = malloc(sizeof(struct Storage));
Let's say I'm trying to delete myStruct. If I have some delete function that I point to (with myStruct->delete = deleteStructure), I would like to do something like this:
myStruct.delete();
which would then free() the struct through a self referencing variable inside of said delete function. I'm wondering if there would be a way to have the delete function look like:
void deleteStructure() {
free( /* "this" or some equivalent C self-reference */ );
}
My assumption from research so far is that this is not possible since this is usually only in object oriented programming languages. If this is not possible, I'm wondering what would be the semantically correct way to do this. I'm hoping to make the usage of this delete functionality rather simplistic from a user interface perspective. The only way I understand this to work would be passing a reference to the structure like:
void deleteStructure(struct Storage *someStructure) {
free(someStructure);
}
which would then require deletion to be done as follows:
deleteStructure(myStruct);
To sum up: is there a way to make a delete function that uses self references in C, and if not, what would be the most semantically correct way to delete a structure in the most user friendly way?
No. You cannot even define a function for a struct.
struct Storage {
void (*delete)();
}
simply stores a pointer to a void function. That could be any void function and when it is being called, it has no connection to Storage whatsoever.
Also note that in your code, every instance of the struct stores one pointer to a void function. You could initialize them so that they all point to the same function, in which case you would simply waste 64 bit per instance without any real benefit. You could also make them point to completely different functions with different semantics.
As per #UnholySheep's comment, the correct semantical use of a struct with connection to a C function will follow the structure:
struct Storage {
/* Some definitions here */
}
void deleteStructure(struct Storage *someStructure) {
free( /* all inner structure allocations */ );
free(someStructure);
}
Here's more about passing structs by reference.

How to make a typedef as private as possible without using Malloc?

I am looking for a way to make private style typedefs that can only be accessed or manipulated from a specific set of function calls (setBit(bit_typ *const t), getBit(bit_typ *const t)). I am looking for a way to do this without using malloc, does anyone have any ideas?
EDIT:// this question is different than this one because it is looking for ways to get as close to a "private" structure whereas the other question (TL;DR is there a way to define an opaque type which can nonetheless be allocated on stack, and without breaking strict aliasing rule ?) looks for a solution to a problem related to one possible solution to my question.
One way to do it is to expose the total size of the opaque type and make used declare the objects of your opaque type as unsigned char [N] buffers. For example, let's say you have some type OpaqueType, internals of which you want to hide from the user.
In the header file (exposed to the user) you do this
typedef unsigned char OpaqueType[16];
where 16 is the exact byte-size of the type you want to hide. In the header file you write the whole interface in terms of that type, e.g.
void set_data(OpaqueType *dst, int data);
In the implementation file you declare the actual type
typedef struct OpaqueTypeImpl
{
int data1;
double data2;
} OpaqueTypeImpl;
and implement the functions as follows
void set_data(OpaqueType *dst, int data)
{
OpaqueTypeImpl *actual_dst = (OpaqueTypeImpl *) dst;
actual_dst->data1 = data;
}
You can also add a static assertion that will make sure that sizeof(OpaqueType) is the same as sizeof(OpaqueTypeImpl).
Of course, as it has been noted in the comments below, extra steps have to be taken to ensure the proper alignment of such objects, like _Alignas in C11 or some union-based technique in "classic" C.
That way you give the user opportunity to declare non-dynamic object of OpaqueType, i.e. you don't force the user to call your function that will malloc such objects internally. And at the same time you don't expose to user anything about the inner structure of your type (besides its total size and its alignment requirement).
Note also that OpaqueType declared in that way is an array, meaning that it is not copyable (unless you use memcpy). That might be a good thing, if you want to actively prevent unrestrained user-level copying. But if you want to enable copying, you can wrap the array into a struct.
This approach is not terribly elegant, but that's probably the only way to hide implementation when you want to keep objects of your type freely user-definable.

Exposing only void pointers in an API

I've seen a good deal of C libraries that do not present the objects they deal with internally as distinct types, but instead wrap them with void pointers before letting you access them. In practice, the "private" source files look something like:
typedef struct {
int value;
} object;
void * object_new(void)
{
object *o = malloc(sizeof(object));
o->value = 1;
return o;
}
int object_get(void *o)
{
return (object *)o->value;
}
void * object_free(void *o)
{
free(o);
}
And in the main header you have only:
void * object_new(void);
int object_get(void *o);
void * object_free(void *o);
Now I wonder: is there a particular reason they do so? If the idea is to ensure the API user has no access to the internals of the object, isn't it sufficient to only expose the type name in the main library header, and to hide the details of the underlying structure (or whatever be the actual object) in the implementation files?
The reason to hide the types behind void pointers could be a (misguided) attempt to hide (in the sense of modular programming) the internal details. This is dangerous, as it throws any type checking the compiler might do right out the window.
Better would be something along the lines:
for-user.h:
struct internalstuff;
void somefunc(struct internalstuff *p);
for-internal-use.h:
#include "for-user.h"
struct internalstuff { ...};
implementation.c:
#include "for-internal-use.h";
void somefunc(struct internalstuff *p)
{
...
}
This way nobody will mix up internalstuff with a random string or the raw result from malloc(3) without getting at least a warning. As long as you only mention pointers to struct internalstuff in C it is fine not to have the definition of the struct at hand.
Something along the same lines can be done in C++ with class, and I'd be suprised if Objective C doesn't allow the same. But the object oriented programming languages have their own, much more flexible, tools for this. There you can define a bare-bones base class to export, while internally extensions are used. Take a look at a good C++ book for details (there are extensive lists here).
In a world of objects (Obj-C and C++), I believe the reason is mostly to do with inheritance. If a subclass is created from the base class, then there is no problem with the type of the return value when creating a new instance of the class. With just straight C, there does not appear to be a clear cut reason as no internal details are revealed or dependencies created.
You're correct.. the idea in most of these cases is to restrict the API user from the internals of the object. The decision about type names though really is just a matter of style. If you were to expose the type name in the header as you suggest (which some APIs do), it would probably look something like:
typedef void* object;
There is no real advantage or disadvantage to doing this from the compiler's point of view. Although it does give the API user a better understanding of what's going on:
object object_new(void);
int object_get(object o);
void object_free(object o);

C modify const members in a struct

I am designing an API and the key part of it is a struct returned by the API with lots of const members. Also, there are both const pointers and pointers to const variables. Inside the implementation I need to modify this struct. Currently, I have defined exactly the same struct but with dropped const keywords and a different name. Inside the API calls I just cast external struct to the internal one.
Is there any way to code in a better way? The current design is prone to errors if I modify one struct and forget about the other.
Use opaque structs and accessor functions
The opaque structs provide a name for your API, but no way to address the fields.
The accessor functions in your API provide whatever controlled access you like.
Just a note here: These field aren't really non writable.
You want to make them kinda "private" but every programmer can access them this way:
typedef struct
{
const int x;
}mystruct;
Then:
mystruct ms= {0};
*((int*)&(ms.x)) =4;
printf("%d",ms.x);
Because the const specifier just prevents programmers from modifying them at compile time.But at runtime the memory isn't readonly.
I still think that the const specifier is useful: if a good programmer sees it, says then I shouldn't access that field.If instead wants to make the smart guy access the fields and potentially risk an inconsistent state.
So if you are sure that these const field can be changed, at your place I would use this way.I know that pedantic programmer will not like it, I don't like it too but sometimes we gotta bypass this.
Duplication is the root of all evil, so instead of duplicating the structure definition you could do something like this:
#ifndef CONST
#define CONST const
#endif
struct mystruct
{
CONST void * my_data;
};
Now you just define CONST to be empty before including the header file in the private implementation.
However, like the other answers suggest, this is not a very good idea. First there's probably better and cleaner ways of acheiving what you want. Second this could lead to strange and unwanted results as the compiler may use the constness of the fields to optimize the code.
In short, I think you would be better off rethinking your API.

Resources