-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggestion on smart arrays #7
Comments
Thanks for the suggestions :)
Once I'm done with other things, I will most probably add some kind of opaque weak pointer if I find a proper way without any race condition.
Will try. I'm not sure if gcc will let me make a conditional branching for pointer/non-pointer types though. Also, for the metadata part, I'm not quite sure what you mean, as I think I already do this -- the actual metadata is prepended with the length of the array and and the size of the base type, and both are accessible with functions in
It should be possible, but then again, I wouldn't know if the passed type is specifically a pointer, or even a pointer managed by libcsptr. I could specify some kind of universal destructor for arrays that you could pass by default though. What I could do, maybe, is to stringify the type, then try to parse the string to see if it is a pointer type -- which is in my opinion a bit overkill; but that still wouldn't solve the problem of knowing if a pointer is a smart pointer. So now, it's more of a preference between 1) // void sfree2(void *ptr, void *meta);
unique_ptr(type*[x], .dtor = sfree2); // array contents are smart pointers
unique_ptr(type*[x]); // array contents are plain pointers and 2) unique_ptr(type*[x]); // array contents are smart pointers
unique_ptr(type*[x], .dtor = NULL); // array contents are plain pointers Now the issue is that while you could expect 2) to make more sense since you would expect people to recursively use smart pointers, it's actually the solution that would in my opinion surprise the programmer the most. If type* is by accident (or by misuse) a plain pointer type, then 1), however, would just cause a (very identifiable) memory leak if it were to be misused, and is (I think) prefered; if the type is managed, set the destructor to the |
|
Opaque in the sense of not providing the contents of the weak_ptr struct, as it would be unsafe to access it without checking if the referred shared_ptr is alive. I was thinking of something like so: struct weak_ptr_s;
typedef struct weak_ptr_s *weak_ptr;
// Usage
smart weak_ptr w;
{
smart int *shared = shared_ptr(int);
w = weak_from(shared);
smart int *ref = weak_lock(w);
assert(ref == shared);
} // shared ptr is destroyed
smart int *nullref = weak_lock(w);
assert(nullref == NULL);
Since I have the liberty of using GNU C extensions, I'm using a simple trick I came up with using const int arrlen = 10;
int[arrlen][1] dummy;
assert(sizeof (dummy[0]) == sizeof (int));
assert(sizeof (dummy) / sizeof (dummy[0]) == arrlen); Then you can abstract the type int[arrlen] away with typeof inside a macro: # define example(Type, ArrLen, ArrEltSize) \
do { \
typeof(Type[1]) dummy; \
*ArrLen = sizeof (dummy) / sizeof (dummy[0]); \
*ArrEltSize = sizeof (dummy[0]); \
} while (0) The array of size 1 is here to make the compiler accept dummy[0] for both scalar and array types, while still having a valid
Well it is, in fact, set as the actual metadata; if you invoke struct user_meta {
int foo, bar;
};
struct array_meta {
s_meta_array;
struct user_meta;
};
smart int* ptr = unique_ptr(int[10], .meta = { &(struct user_meta) { 1, 2 }, sizeof (struct user_meta) });
struct array_meta *meta = get_smart_ptr_meta(ptr); But I would recommend to use
That is also my view, although I explained it poorly. I plan to provide the two universal |
|
Firstly, I must commend you on a very nice library here. Creating a library for smarter pointers in C and doing it in a way that is compatible with the syntax and style of the language is a real step forward for people like me who want to try high-level programming in C. Keep up the good work, and I'd be curious to hear if you have any plans for further features/updates. (I like that it's a small library right now though, and quite minimalistic as is C as a whole.)
Regarding "smart arrays" specifically: I like that the library can infer the size of fixed-size arrays and use this to automate the destructor more. However, I personally imagine that implementing this in another way would be more general and extensible:
size_t
containing that size, and also set the default destructor to a function that doessfree
on each element of the array (if the element type is a pointer) and nothing (if the element type is a non-pointer).unique_ptr
orshared_ptr
macro call.Anyway, let me know what you think, and maybe we can establish what sort of interface for smart arrays is best. The design of the library in general is great, of course. :)
The text was updated successfully, but these errors were encountered: