diff options
| author | Tyge Løvset <[email protected]> | 2022-05-05 14:05:25 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-05-05 14:05:25 +0200 |
| commit | dc08853f66e40a9a23c7f6b344d51254e10c628e (patch) | |
| tree | a2bdbbaba2e2d81c1fd09439bc5c2385d70f50e3 /include/stc | |
| parent | 70551d3af9e30d75a6a6373787ff1432feebee26 (diff) | |
| download | STC-modified-dc08853f66e40a9a23c7f6b344d51254e10c628e.tar.gz STC-modified-dc08853f66e40a9a23c7f6b344d51254e10c628e.zip | |
Added type-checked c_container_of() macro using typeof (C23, gcc, clang, tcc). c_unchecked_container_of() must be used by lib.
Diffstat (limited to 'include/stc')
| -rw-r--r-- | include/stc/alt/cstr.h | 2 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 14 | ||||
| -rw-r--r-- | include/stc/cdeq.h | 4 | ||||
| -rw-r--r-- | include/stc/clist.h | 2 | ||||
| -rw-r--r-- | include/stc/csmap.h | 10 | ||||
| -rw-r--r-- | include/stc/cvec.h | 4 |
6 files changed, 21 insertions, 15 deletions
diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 3dc72178..ec7f3bba 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -34,7 +34,7 @@ #define cstr_npos (SIZE_MAX >> 1)
typedef struct { size_t size, cap; char chr[1]; } cstr_priv;
-#define _cstr_p(self) c_container_of((self)->str, cstr_priv, chr)
+#define _cstr_p(self) c_unchecked_container_of((self)->str, cstr_priv, chr)
#ifdef _i_static
static cstr_priv _cstr_nullrep = {0, 0, {0}};
static const cstr cstr_null = {_cstr_nullrep.chr};
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 8885626c..b96cf547 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -55,9 +55,15 @@ #define c_static_assert(cond) \
typedef char c_paste(_static_assert_line_, __LINE__)[(cond) ? 1 : -1]
-#define c_container_of(ptr, type, member) \
+#define c_unchecked_container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
-
+#if defined _MSC_VER && __STDC_VERSION__ < 202300L
+# define c_container_of(p,t,m) c_unchecked_container_of(p,t,m)
+#else
+# define c_container_of(ptr, type, member) \
+ ((typeof(ptr))0 == (typeof(&((type *)0)->member))0, \
+ ((type *)((char *)(ptr) - offsetof(type, member))))
+#endif
#ifndef __cplusplus
# define c_alloc(T) c_malloc(sizeof(T))
# define c_alloc_n(T, n) c_malloc(sizeof(T)*(n))
@@ -216,9 +222,9 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, size_t slen, cons #define c_find_if(vp, C, cnt, pred) do { \
size_t index = 0; \
C##_iter _it = C##_begin(&cnt), _end = C##_end(&cnt); \
- for (; vp = _it.ref, _it.ref != _end.ref && !(pred); C##_next(&_it)) \
+ for (; vp = _it.ref, vp != _end.ref && !(pred); C##_next(&_it)) \
++index; \
- if (_it.ref == _end.ref) vp = NULL; \
+ if (vp == _end.ref) vp = NULL; \
} while (0)
#define c_drop(C, ...) do { \
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 6c92ba4a..77d2cf71 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -27,8 +27,8 @@ #include <stdlib.h>
#include <string.h>
-struct cdeq_rep { size_t size, cap; void* base[]; };
-#define cdeq_rep_(self) c_container_of((self)->_base, struct cdeq_rep, base)
+struct cdeq_rep { size_t size, cap; unsigned base[1]; };
+#define cdeq_rep_(self) c_unchecked_container_of((self)->_base, struct cdeq_rep, base)
#endif // CDEQ_H_INCLUDED
#ifndef _i_prefix
diff --git a/include/stc/clist.h b/include/stc/clist.h index 05a7b58e..9b4560c7 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -64,7 +64,7 @@ SELF##_value value; \
}
-#define clist_node_(vp) c_container_of(vp, _cx_node, value)
+#define clist_node_(vp) c_unchecked_container_of(vp, _cx_node, value)
_c_clist_types(clist_VOID, int);
_c_clist_complete_types(clist_VOID, dummy);
diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 89881444..c7bf8e47 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -55,8 +55,8 @@ int main(void) { #include <stdlib.h>
#include <string.h>
-struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; };
-#define _csmap_rep(self) c_container_of((self)->nodes, struct csmap_rep, nodes)
+struct csmap_rep { size_t root, disp, head, size, cap; unsigned nodes[1]; };
+#define _csmap_rep(self) c_unchecked_container_of((self)->nodes, struct csmap_rep, nodes)
#endif // CSMAP_H_INCLUDED
#ifndef _i_prefix
@@ -253,11 +253,11 @@ _cx_memb(_reserve)(_cx_self* self, const size_t cap) { if (cap >= rep->size) {
// second test is bogus, but supresses gcc warning:
oldrep = rep->cap && rep != &_csmap_sentinel ? rep : NULL;
- rep = (struct csmap_rep*) c_realloc(oldrep, sizeof(struct csmap_rep) +
+ rep = (struct csmap_rep*) c_realloc(oldrep, offsetof(struct csmap_rep, nodes) +
(cap + 1)*sizeof(_cx_node));
if (!rep) return false;
if (oldrep == NULL)
- memset(rep, 0, sizeof(struct csmap_rep) + sizeof(_cx_node));
+ memset(rep, 0, offsetof(struct csmap_rep, nodes) + sizeof(_cx_node));
rep->cap = cap;
self->nodes = (_cx_node *) rep->nodes;
}
@@ -451,7 +451,7 @@ _cx_memb(_erase_r_)(_cx_node *d, i_size tn, const _cx_rawkey* rkey, int *erased) tx = tn;
tn = d[tn].link[ d[tn].link[0] == 0 ];
/* move it to disposed nodes list */
- struct csmap_rep *rep = c_container_of(d, struct csmap_rep, nodes);
+ struct csmap_rep *rep = c_unchecked_container_of(d, struct csmap_rep, nodes);
d[tx].link[1] = (i_size) rep->disp;
rep->disp = tx;
}
diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 24cf8249..83c8680d 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -64,8 +64,8 @@ int main() { #include <stdlib.h>
#include <string.h>
-struct cvec_rep { size_t size, cap; void* data[]; };
-#define cvec_rep_(self) c_container_of((self)->data, struct cvec_rep, data)
+struct cvec_rep { size_t size, cap; unsigned data[1]; };
+#define cvec_rep_(self) c_unchecked_container_of((self)->data, struct cvec_rep, data)
#endif // CVEC_H_INCLUDED
#ifndef _i_prefix
|
