ucx/cx/common.h

changeset 1040
473d8cb58a6c
parent 992
f421aef8f865
equal deleted inserted replaced
1039:6691e007cef7 1040:473d8cb58a6c
131 #endif 131 #endif
132 132
133 /** 133 /**
134 * Inform the compiler that falling through a switch case is intentional. 134 * Inform the compiler that falling through a switch case is intentional.
135 */ 135 */
136 #define cx_attr_fallthrough __attribute__((__fallthrough__)) 136 #define CX_FALLTHROUGH __attribute__((__fallthrough__))
137 137
138 /** 138 /**
139 * All pointer arguments must be non-NULL. 139 * All pointer arguments must be non-NULL.
140 */ 140 */
141 #define cx_attr_nonnull __attribute__((__nonnull__)) 141 #define CX_NONNULL __attribute__((__nonnull__))
142 142
143 /** 143 /**
144 * The specified pointer arguments must be non-NULL. 144 * The specified pointer arguments must be non-NULL.
145 */ 145 */
146 #define cx_attr_nonnull_arg(...) __attribute__((__nonnull__(__VA_ARGS__))) 146 #define CX_NONNULL_ARG(...) __attribute__((__nonnull__(__VA_ARGS__)))
147 147
148 /** 148 /**
149 * The returned value is guaranteed to be non-NULL. 149 * The returned value is guaranteed to be non-NULL.
150 */ 150 */
151 #define cx_attr_returns_nonnull __attribute__((__returns_nonnull__)) 151 #define CX_RETURNS_NONNULL __attribute__((__returns_nonnull__))
152 152
153 /** 153 /**
154 * The attributed function always returns freshly allocated memory. 154 * The attributed function always returns freshly allocated memory.
155 */ 155 */
156 #define cx_attr_malloc __attribute__((__malloc__)) 156 #define CX_MALLOC __attribute__((__malloc__))
157 157
158 #if !defined(__clang__) && __GNUC__ >= 11 158 #if !defined(__clang__) && __GNUC__ >= 11
159 /** 159 /**
160 * The pointer returned by the attributed function is supposed to be freed 160 * The pointer returned by the attributed function is supposed to be freed
161 * by @p freefunc. 161 * by @p freefunc.
162 * 162 *
163 * @param freefunc the function that shall be used to free the memory 163 * @param freefunc the function that shall be used to free the memory
164 * @param freefunc_arg the index of the pointer argument in @p freefunc 164 * @param freefunc_arg the index of the pointer argument in @p freefunc
165 */ 165 */
166 #define cx_attr_dealloc(freefunc, freefunc_arg) \ 166 #define CX_DEALLOC(freefunc, freefunc_arg) \
167 __attribute__((__malloc__(freefunc, freefunc_arg))) 167 __attribute__((__malloc__(freefunc, freefunc_arg)))
168 #else 168 #else
169 /** 169 /**
170 * Not supported in clang. 170 * Not supported in clang.
171 */ 171 */
172 #define cx_attr_dealloc(...) 172 #define CX_DEALLOC(...)
173 #endif // __clang__ 173 #endif // __clang__
174 174
175 /** 175 /**
176 * Shortcut to specify #cxFree() as deallocator. 176 * Shortcut to specify #cxFree() as deallocator.
177 */ 177 */
178 #define cx_attr_dealloc_ucx cx_attr_dealloc(cxFree, 2) 178 #define CX_DEALLOC_UCX CX_DEALLOC(cxFree, 2)
179 179
180 /** 180 /**
181 * Specifies the parameters from which the allocation size is calculated. 181 * Specifies the parameters from which the allocation size is calculated.
182 */ 182 */
183 #define cx_attr_allocsize(...) __attribute__((__alloc_size__(__VA_ARGS__))) 183 #define CX_ALLOCSIZE(...) __attribute__((__alloc_size__(__VA_ARGS__)))
184 184
185 185
186 #ifdef __clang__ 186 #ifdef __clang__
187 /** 187 /**
188 * No support for @c null_terminated_string_arg in clang or GCC below 14. 188 * No support for @c null_terminated_string_arg in clang or GCC below 14.
189 */ 189 */
190 #define cx_attr_cstr_arg(idx) 190 #define CX_CSTR_ARG(idx)
191 /** 191 /**
192 * No support for the access attribute in clang. 192 * No support for the access attribute in clang.
193 */ 193 */
194 #define cx_attr_access(mode, ...) 194 #define CX_ACCESS(mode, ...)
195 #else 195 #else
196 #if __GNUC__ < 10 196 #if __GNUC__ < 10
197 /** 197 /**
198 * No support for access attribute in GCC < 10. 198 * No support for access attribute in GCC < 10.
199 */ 199 */
200 #define cx_attr_access(mode, ...) 200 #define CX_ACCESS(mode, ...)
201 #else 201 #else
202 /** 202 /**
203 * Helper macro to define access macros. 203 * Helper macro to define access macros.
204 */ 204 */
205 #define cx_attr_access(mode, ...) __attribute__((__access__(mode, __VA_ARGS__))) 205 #define CX_ACCESS(mode, ...) __attribute__((__access__(mode, __VA_ARGS__)))
206 #endif // __GNUC__ < 10 206 #endif // __GNUC__ < 10
207 #if __GNUC__ < 14 207 #if __GNUC__ < 14
208 /** 208 /**
209 * No support for @c null_terminated_string_arg in clang or GCC below 14. 209 * No support for @c null_terminated_string_arg in clang or GCC below 14.
210 */ 210 */
211 #define cx_attr_cstr_arg(idx) 211 #define CX_CSTR_ARG(idx)
212 #else 212 #else
213 /** 213 /**
214 * The specified argument is expected to be a zero-terminated string. 214 * The specified argument is expected to be a zero-terminated string.
215 * 215 *
216 * @param idx the index of the argument 216 * @param idx the index of the argument
217 */ 217 */
218 #define cx_attr_cstr_arg(idx) \ 218 #define CX_CSTR_ARG(idx) \
219 __attribute__((__null_terminated_string_arg__(idx))) 219 __attribute__((__null_terminated_string_arg__(idx)))
220 #endif // __GNUC__ < 14 220 #endif // __GNUC__ < 14
221 #endif // __clang__ 221 #endif // __clang__
222 222
223 223
225 * Specifies that the function will only read through the given pointer. 225 * Specifies that the function will only read through the given pointer.
226 * 226 *
227 * Takes one or two arguments: the index of the pointer and (optionally) the 227 * Takes one or two arguments: the index of the pointer and (optionally) the
228 * index of another argument specifying the maximum number of accessed bytes. 228 * index of another argument specifying the maximum number of accessed bytes.
229 */ 229 */
230 #define cx_attr_access_r(...) cx_attr_access(__read_only__, __VA_ARGS__) 230 #define CX_ACCESS_R(...) CX_ACCESS(__read_only__, __VA_ARGS__)
231 231
232 /** 232 /**
233 * Specifies that the function will read and write through the given pointer. 233 * Specifies that the function will read and write through the given pointer.
234 * 234 *
235 * Takes one or two arguments: the index of the pointer and (optionally) the 235 * Takes one or two arguments: the index of the pointer and (optionally) the
236 * index of another argument specifying the maximum number of accessed bytes. 236 * index of another argument specifying the maximum number of accessed bytes.
237 */ 237 */
238 #define cx_attr_access_rw(...) cx_attr_access(__read_write__, __VA_ARGS__) 238 #define CX_ACCESS_RW(...) CX_ACCESS(__read_write__, __VA_ARGS__)
239 239
240 /** 240 /**
241 * Specifies that the function will only write through the given pointer. 241 * Specifies that the function will only write through the given pointer.
242 * 242 *
243 * Takes one or two arguments: the index of the pointer and (optionally) the 243 * Takes one or two arguments: the index of the pointer and (optionally) the
244 * index of another argument specifying the maximum number of accessed bytes. 244 * index of another argument specifying the maximum number of accessed bytes.
245 */ 245 */
246 #define cx_attr_access_w(...) cx_attr_access(__write_only__, __VA_ARGS__) 246 #define CX_ACCESS_W(...) CX_ACCESS(__write_only__, __VA_ARGS__)
247 247
248 /** 248 /**
249 * Do not warn about unused variable. 249 * Do not warn about unused variable.
250 */ 250 */
251 #define cx_attr_unused __attribute__((__unused__)) 251 #define CX_UNUSED __attribute__((__unused__))
252 252
253 /** 253 /**
254 * Warn about discarded return value. 254 * Warn about discarded return value.
255 */ 255 */
256 #define cx_attr_nodiscard __attribute__((__warn_unused_result__)) 256 #define CX_NODISCARD __attribute__((__warn_unused_result__))
257 257
258 258
259 // --------------------------------------------------------------------------- 259 // ---------------------------------------------------------------------------
260 // MSVC specifics 260 // Support for thread_local
261 // --------------------------------------------------------------------------- 261 // ---------------------------------------------------------------------------
262 262
263 #ifdef __cplusplus
264 #define cx_thread_local thread_local
265 #else // ! __cplusplus
263 #ifdef _MSC_VER 266 #ifdef _MSC_VER
264 // fix missing _Thread_local support 267 #define cx_thread_local __declspec(thread)
265 #define _Thread_local __declspec(thread) 268 #else // ! _MSC_VER
269 #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 202300L
270 /** Platform independent thread-local macro. */
271 #define cx_thread_local _Thread_local
272 #else // C23 or newer
273 /** Platform independent thread-local macro. */
274 #define cx_thread_local thread_local
275 #endif // C23
266 #endif // _MSC_VER 276 #endif // _MSC_VER
277 #endif // __cplusplus
267 278
268 // --------------------------------------------------------------------------- 279 // ---------------------------------------------------------------------------
269 // Exported and inlined functions 280 // Exported and inlined functions
270 // --------------------------------------------------------------------------- 281 // ---------------------------------------------------------------------------
271 282
275 #define CX_EXPORT __declspec(dllimport) 286 #define CX_EXPORT __declspec(dllimport)
276 #else 287 #else
277 /** Only used for building Windows DLLs. */ 288 /** Only used for building Windows DLLs. */
278 #define CX_EXPORT 289 #define CX_EXPORT
279 #endif // CX_WINDLL / CX_WINDLL_EXPORT 290 #endif // CX_WINDLL / CX_WINDLL_EXPORT
291
292 #ifdef __cplusplus
293 #define CX_EXTERN extern "C" CX_EXPORT
294 #define CX_FPTR extern "C" typedef
295 #else
296 /** Declares a function with external linkage. */
297 #define CX_EXTERN CX_EXPORT
298 /** Defines a function pointer. */
299 #define CX_FPTR typedef
300 #endif
280 301
281 #ifdef __GNUC__ 302 #ifdef __GNUC__
282 /** 303 /**
283 * Declares a function to be inlined. 304 * Declares a function to be inlined.
284 */ 305 */
353 * @param result a pointer to a variable, where the result should 374 * @param result a pointer to a variable, where the result should
354 * be stored 375 * be stored
355 * @retval zero success 376 * @retval zero success
356 * @retval non-zero the multiplication would overflow 377 * @retval non-zero the multiplication would overflow
357 */ 378 */
358 #if __cplusplus 379 CX_EXTERN
359 extern "C" 380 int cx_szmul_impl(size_t a, size_t b, size_t *result);
360 #endif
361 CX_EXPORT int cx_szmul_impl(size_t a, size_t b, size_t *result);
362 #endif // cx_szmul 381 #endif // cx_szmul
363 382
364 #endif // UCX_COMMON_H 383 #endif // UCX_COMMON_H

mercurial