src/cx/common.h

changeset 985
68754c7de906
parent 970
c9b02747cfc5
equal deleted inserted replaced
984:e8f354a25ac8 985:68754c7de906
86 #define UCX_VERSION_MINOR 1 86 #define UCX_VERSION_MINOR 1
87 87
88 /** Version constant which ensures to increase monotonically. */ 88 /** Version constant which ensures to increase monotonically. */
89 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR) 89 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR)
90 90
91 // Common Includes 91 // ---------------------------------------------------------------------------
92 // Common includes
93 // ---------------------------------------------------------------------------
92 94
93 #include <stdlib.h> 95 #include <stdlib.h>
94 #include <stddef.h> 96 #include <stddef.h>
95 #include <stdbool.h> 97 #include <stdbool.h>
96 #include <stdint.h> 98 #include <stdint.h>
99
100 // ---------------------------------------------------------------------------
101 // Attribute definitions
102 // ---------------------------------------------------------------------------
103
104 #ifndef __GNUC__
105 /**
106 * Removes GNU C attributes where they are not supported.
107 */
108 #define __attribute__(x)
109 #endif
110
111 /**
112 * All pointer arguments must be non-NULL.
113 */
114 #define cx_attr_nonnull __attribute__((__nonnull__))
115
116 /**
117 * The specified pointer arguments must be non-NULL.
118 */
119 #define cx_attr_nonnull_arg(...) __attribute__((__nonnull__(__VA_ARGS__)))
120
121 /**
122 * The returned value is guaranteed to be non-NULL.
123 */
124 #define cx_attr_returns_nonnull __attribute__((__returns_nonnull__))
125
126 /**
127 * The attributed function always returns freshly allocated memory.
128 */
129 #define cx_attr_malloc __attribute__((__malloc__))
130
131 #ifndef __clang__
132 /**
133 * The pointer returned by the attributed function is supposed to be freed
134 * by \p freefunc.
135 *
136 * @param freefunc the function that shall be used to free the memory
137 * @param freefunc_arg the index of the pointer argument in \p freefunc
138 */
139 #define cx_attr_dealloc(freefunc, freefunc_arg) \
140 __attribute__((__malloc__(freefunc, freefunc_arg)))
141 #else
142 /**
143 * Not supported in clang.
144 */
145 #define cx_attr_dealloc(...)
146 #endif // __clang__
147
148 /**
149 * Shortcut to specify #cxFree() as deallocator.
150 */
151 #define cx_attr_dealloc_ucx cx_attr_dealloc(cxFree, 2)
152
153 /**
154 * Specifies the parameters from which the allocation size is calculated.
155 */
156 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__)))
157
158
159 #ifdef __clang__
160 /**
161 * No support for \c null_terminated_string_arg in clang or GCC below 14.
162 */
163 #define cx_attr_cstr_arg(idx)
164 /**
165 * No support for access attribute in clang.
166 */
167 #define cx_attr_access(mode, ...)
168 #else
169 #if __GNUC__ < 10
170 /**
171 * No support for access attribute in GCC < 10.
172 */
173 #define cx_attr_access(mode, ...)
174 #else
175 /**
176 * Helper macro to define access macros.
177 */
178 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__)))
179 #endif // __GNUC__ < 10
180 #if __GNUC__ < 14
181 /**
182 * No support for \c null_terminated_string_arg in clang or GCC below 14.
183 */
184 #define cx_attr_cstr_arg(idx)
185 #else
186 /**
187 * The specified argument is expected to be a zero-terminated string.
188 *
189 * @param idx the index of the argument
190 */
191 #define cx_attr_cstr_arg(idx) \
192 __attribute__((__null_terminated_string_arg__(idx)))
193 #endif // __GNUC__ < 14
194 #endif // __clang__
195
196
197 /**
198 * Specifies that the function will only read through the given pointer.
199 *
200 * Takes one or two arguments: the index of the pointer and (optionally) the
201 * index of another argument specifying the maximum number of accessed bytes.
202 */
203 #define cx_attr_access_r(...) cx_attr_access(__read_only__, __VA_ARGS__)
204
205 /**
206 * Specifies that the function will read and write through the given pointer.
207 *
208 * Takes one or two arguments: the index of the pointer and (optionally) the
209 * index of another argument specifying the maximum number of accessed bytes.
210 */
211 #define cx_attr_access_rw(...) cx_attr_access(__read_write__, __VA_ARGS__)
212
213 /**
214 * Specifies that the function will only write through the given pointer.
215 *
216 * Takes one or two arguments: the index of the pointer and (optionally) the
217 * index of another argument specifying the maximum number of accessed bytes.
218 */
219 #define cx_attr_access_w(...) cx_attr_access(__write_only__, __VA_ARGS__)
220
221 #if __STDC_VERSION__ >= 202300L
222
223 /**
224 * Do not warn about unused variable.
225 */
226 #define cx_attr_unused [[maybe_unused]]
227
228 /**
229 * Warn about discarded return value.
230 */
231 #define cx_attr_nodiscard [[nodiscard]]
232
233 #else // no C23
234
235 /**
236 * Do not warn about unused variable.
237 */
238 #define cx_attr_unused __attribute__((__unused__))
239
240 /**
241 * Warn about discarded return value.
242 */
243 #define cx_attr_nodiscard __attribute__((__warn_unused_result__))
244
245 #endif // __STDC_VERSION__
246
247 // ---------------------------------------------------------------------------
248 // Useful function pointers
249 // ---------------------------------------------------------------------------
97 250
98 /** 251 /**
99 * Function pointer compatible with fwrite-like functions. 252 * Function pointer compatible with fwrite-like functions.
100 */ 253 */
101 typedef size_t (*cx_write_func)( 254 typedef size_t (*cx_write_func)(
102 const void *, 255 const void *,
103 size_t, 256 size_t,
104 size_t, 257 size_t,
105 void * 258 void *
106 ); 259 ) cx_attr_nonnull;
107 260
108 /** 261 /**
109 * Function pointer compatible with fread-like functions. 262 * Function pointer compatible with fread-like functions.
110 */ 263 */
111 typedef size_t (*cx_read_func)( 264 typedef size_t (*cx_read_func)(
112 void *, 265 void *,
113 size_t, 266 size_t,
114 size_t, 267 size_t,
115 void * 268 void *
116 ); 269 ) cx_attr_nonnull;
270
271 // ---------------------------------------------------------------------------
272 // Utility macros
273 // ---------------------------------------------------------------------------
117 274
118 /** 275 /**
119 * Determines the number of members in a static C array. 276 * Determines the number of members in a static C array.
120 * 277 *
121 * @attention never use this to determine the size of a dynamically allocated 278 * @attention never use this to determine the size of a dynamically allocated
124 * @param arr the array identifier 281 * @param arr the array identifier
125 * @return the number of elements 282 * @return the number of elements
126 */ 283 */
127 #define cx_nmemb(arr) (sizeof(arr)/sizeof((arr)[0])) 284 #define cx_nmemb(arr) (sizeof(arr)/sizeof((arr)[0]))
128 285
129 // cx_szmul() definition 286 // ---------------------------------------------------------------------------
287 // szmul implementation
288 // ---------------------------------------------------------------------------
289
130 #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN) 290 #if (__GNUC__ >= 5 || defined(__clang__)) && !defined(CX_NO_SZMUL_BUILTIN)
131 #define CX_SZMUL_BUILTIN 291 #define CX_SZMUL_BUILTIN
132 292
133 /** 293 /**
134 * Alias for \c __builtin_mul_overflow. 294 * Alias for \c __builtin_mul_overflow.
172 */ 332 */
173 int cx_szmul_impl(size_t a, size_t b, size_t *result); 333 int cx_szmul_impl(size_t a, size_t b, size_t *result);
174 334
175 #endif // cx_szmul 335 #endif // cx_szmul
176 336
177 // Compiler specific stuff 337
178 338 // ---------------------------------------------------------------------------
179 #ifndef __GNUC__ 339 // Fixes for MSVC incompatibilities
180 /** 340 // ---------------------------------------------------------------------------
181 * Removes GNU C attributes where they are not supported.
182 */
183 #define __attribute__(x)
184 #endif
185 341
186 #ifdef _MSC_VER 342 #ifdef _MSC_VER
187
188 // fix missing ssize_t definition 343 // fix missing ssize_t definition
189 #include <BaseTsd.h> 344 #include <BaseTsd.h>
190 typedef SSIZE_T ssize_t; 345 typedef SSIZE_T ssize_t;
191 346
192 // fix missing _Thread_local support 347 // fix missing _Thread_local support
193 #define _Thread_local __declspec(thread) 348 #define _Thread_local __declspec(thread)
194 349 #endif // _MSC_VER
195 #endif
196 350
197 #endif // UCX_COMMON_H 351 #endif // UCX_COMMON_H

mercurial