macros: add G_GNUC_CHECK_VERSION() for compiler checks.
[glib.git] / glib / gmacros.h
blob9b057ceb0a8f1bb32ec65292b5fd44b19cf748c2
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GLib Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 /* This file must not include any other glib header file and must thus
26 * not refer to variables from glibconfig.h
29 #ifndef __G_MACROS_H__
30 #define __G_MACROS_H__
32 #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
33 #error "Only <glib.h> can be included directly."
34 #endif
36 /* We include stddef.h to get the system's definition of NULL
38 #include <stddef.h>
40 #define G_GNUC_CHECK_VERSION(major, minor) \
41 (defined(__GNUC__) && \
42 ((__GNUC__ > (major)) || \
43 ((__GNUC__ == (major)) && \
44 (__GNUC_MINOR__ >= (minor)))))
46 /* Here we provide G_GNUC_EXTENSION as an alias for __extension__,
47 * where this is valid. This allows for warningless compilation of
48 * "long long" types even in the presence of '-ansi -pedantic'.
50 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
51 #define G_GNUC_EXTENSION __extension__
52 #else
53 #define G_GNUC_EXTENSION
54 #endif
56 /* Every compiler that we target supports inlining, but some of them may
57 * complain about it if we don't say "__inline". If we have C99, then
58 * we can use "inline" directly. Otherwise, we say "__inline" to avoid
59 * the warning.
61 #define G_CAN_INLINE
62 #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199900)
63 #undef inline
64 #define inline __inline
65 #endif
67 /* For historical reasons we need to continue to support those who
68 * define G_IMPLEMENT_INLINES to mean "don't implement this here".
70 #ifdef G_IMPLEMENT_INLINES
71 # define G_INLINE_FUNC extern
72 # undef G_CAN_INLINE
73 #else
74 # define G_INLINE_FUNC static inline
75 #endif /* G_IMPLEMENT_INLINES */
77 /* Provide macros to feature the GCC function attribute.
79 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
80 #define G_GNUC_PURE __attribute__((__pure__))
81 #define G_GNUC_MALLOC __attribute__((__malloc__))
82 #else
83 #define G_GNUC_PURE
84 #define G_GNUC_MALLOC
85 #endif
87 #if __GNUC__ >= 4
88 #define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
89 #else
90 #define G_GNUC_NULL_TERMINATED
91 #endif
93 /* Clang feature detection: http://clang.llvm.org/docs/LanguageExtensions.html */
94 #ifndef __has_feature
95 #define __has_feature(x) 0
96 #endif
98 #ifndef __has_builtin
99 #define __has_builtin(x) 0
100 #endif
102 #if (!defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
103 (defined(__clang__) && __has_feature(__alloc_size__))
104 #define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
105 #define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
106 #else
107 #define G_GNUC_ALLOC_SIZE(x)
108 #define G_GNUC_ALLOC_SIZE2(x,y)
109 #endif
111 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
112 #define G_GNUC_PRINTF( format_idx, arg_idx ) \
113 __attribute__((__format__ (__printf__, format_idx, arg_idx)))
114 #define G_GNUC_SCANF( format_idx, arg_idx ) \
115 __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
116 #define G_GNUC_FORMAT( arg_idx ) \
117 __attribute__((__format_arg__ (arg_idx)))
118 #define G_GNUC_NORETURN \
119 __attribute__((__noreturn__))
120 #define G_GNUC_CONST \
121 __attribute__((__const__))
122 #define G_GNUC_UNUSED \
123 __attribute__((__unused__))
124 #define G_GNUC_NO_INSTRUMENT \
125 __attribute__((__no_instrument_function__))
126 #else /* !__GNUC__ */
127 #define G_GNUC_PRINTF( format_idx, arg_idx )
128 #define G_GNUC_SCANF( format_idx, arg_idx )
129 #define G_GNUC_FORMAT( arg_idx )
130 #define G_GNUC_NORETURN
131 #define G_GNUC_CONST
132 #define G_GNUC_UNUSED
133 #define G_GNUC_NO_INSTRUMENT
134 #endif /* !__GNUC__ */
136 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
137 #define G_GNUC_DEPRECATED __attribute__((__deprecated__))
138 #else
139 #define G_GNUC_DEPRECATED
140 #endif /* __GNUC__ */
142 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
143 #define G_GNUC_DEPRECATED_FOR(f) \
144 __attribute__((deprecated("Use " #f " instead")))
145 #else
146 #define G_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED
147 #endif /* __GNUC__ */
149 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
150 #define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
151 _Pragma ("GCC diagnostic push") \
152 _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
153 #define G_GNUC_END_IGNORE_DEPRECATIONS \
154 _Pragma ("GCC diagnostic pop")
155 #elif defined (_MSC_VER) && (_MSC_VER >= 1500)
156 #define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
157 __pragma (warning (push)) \
158 __pragma (warning (disable : 4996))
159 #define G_GNUC_END_IGNORE_DEPRECATIONS \
160 __pragma (warning (pop))
161 #elif defined (__clang__)
162 #define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
163 _Pragma("clang diagnostic push") \
164 _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
165 #define G_GNUC_END_IGNORE_DEPRECATIONS \
166 _Pragma("clang diagnostic pop")
167 #else
168 #define G_GNUC_BEGIN_IGNORE_DEPRECATIONS
169 #define G_GNUC_END_IGNORE_DEPRECATIONS
170 #endif
172 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
173 #define G_GNUC_MAY_ALIAS __attribute__((may_alias))
174 #else
175 #define G_GNUC_MAY_ALIAS
176 #endif
178 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
179 #define G_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
180 #else
181 #define G_GNUC_WARN_UNUSED_RESULT
182 #endif /* __GNUC__ */
184 #ifndef G_DISABLE_DEPRECATED
185 /* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
186 * macros, so we can refer to them as strings unconditionally.
187 * usage not-recommended since gcc-3.0
189 #if defined (__GNUC__) && (__GNUC__ < 3)
190 #define G_GNUC_FUNCTION __FUNCTION__
191 #define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
192 #else /* !__GNUC__ */
193 #define G_GNUC_FUNCTION ""
194 #define G_GNUC_PRETTY_FUNCTION ""
195 #endif /* !__GNUC__ */
196 #endif /* !G_DISABLE_DEPRECATED */
198 #if __has_feature(attribute_analyzer_noreturn) && defined(__clang_analyzer__)
199 #define G_ANALYZER_ANALYZING 1
200 #define G_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
201 #else
202 #define G_ANALYZER_ANALYZING 0
203 #define G_ANALYZER_NORETURN
204 #endif
206 #define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string)
207 #define G_STRINGIFY_ARG(contents) #contents
209 #ifndef __GI_SCANNER__ /* The static assert macro really confuses the introspection parser */
210 #define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
211 #define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2)
212 #ifdef __COUNTER__
213 #define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
214 #else
215 #define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __LINE__)[(expr) ? 1 : -1] G_GNUC_UNUSED
216 #endif
217 #define G_STATIC_ASSERT_EXPR(expr) ((void) sizeof (char[(expr) ? 1 : -1]))
218 #endif
220 /* Provide a string identifying the current code position */
221 #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__cplusplus)
222 #define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()"
223 #else
224 #define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
225 #endif
227 /* Provide a string identifying the current function, non-concatenatable */
228 #if defined (__GNUC__) && defined (__cplusplus)
229 #define G_STRFUNC ((const char*) (__PRETTY_FUNCTION__))
230 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
231 #define G_STRFUNC ((const char*) (__func__))
232 #elif defined (__GNUC__) || (defined(_MSC_VER) && (_MSC_VER > 1300))
233 #define G_STRFUNC ((const char*) (__FUNCTION__))
234 #else
235 #define G_STRFUNC ((const char*) ("???"))
236 #endif
238 /* Guard C code in headers, while including them from C++ */
239 #ifdef __cplusplus
240 #define G_BEGIN_DECLS extern "C" {
241 #define G_END_DECLS }
242 #else
243 #define G_BEGIN_DECLS
244 #define G_END_DECLS
245 #endif
247 /* Provide definitions for some commonly used macros.
248 * Some of them are only provided if they haven't already
249 * been defined. It is assumed that if they are already
250 * defined then the current definition is correct.
252 #ifndef NULL
253 # ifdef __cplusplus
254 # define NULL (0L)
255 # else /* !__cplusplus */
256 # define NULL ((void*) 0)
257 # endif /* !__cplusplus */
258 #endif
260 #ifndef FALSE
261 #define FALSE (0)
262 #endif
264 #ifndef TRUE
265 #define TRUE (!FALSE)
266 #endif
268 #undef MAX
269 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
271 #undef MIN
272 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
274 #undef ABS
275 #define ABS(a) (((a) < 0) ? -(a) : (a))
277 #undef CLAMP
278 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
280 /* Count the number of elements in an array. The array must be defined
281 * as such; using this with a dynamically allocated array will give
282 * incorrect results.
284 #define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
286 /* Macros by analogy to GINT_TO_POINTER, GPOINTER_TO_INT
288 #define GPOINTER_TO_SIZE(p) ((gsize) (p))
289 #define GSIZE_TO_POINTER(s) ((gpointer) (gsize) (s))
291 /* Provide convenience macros for handling structure
292 * fields through their offsets.
295 #if defined(__GNUC__) && __GNUC__ >= 4
296 #define G_STRUCT_OFFSET(struct_type, member) \
297 ((glong) offsetof (struct_type, member))
298 #else
299 #define G_STRUCT_OFFSET(struct_type, member) \
300 ((glong) ((guint8*) &((struct_type*) 0)->member))
301 #endif
303 #define G_STRUCT_MEMBER_P(struct_p, struct_offset) \
304 ((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset)))
305 #define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \
306 (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
308 /* Provide simple macro statement wrappers:
309 * G_STMT_START { statements; } G_STMT_END;
310 * This can be used as a single statement, like:
311 * if (x) G_STMT_START { ... } G_STMT_END; else ...
312 * This intentionally does not use compiler extensions like GCC's '({...})' to
313 * avoid portability issue or side effects when compiled with different compilers.
314 * MSVC complains about "while(0)": C4127: "Conditional expression is constant",
315 * so we use __pragma to avoid the warning since the use here is intentional.
317 #if !(defined (G_STMT_START) && defined (G_STMT_END))
318 #define G_STMT_START do
319 #if defined (_MSC_VER) && (_MSC_VER >= 1500)
320 #define G_STMT_END \
321 __pragma(warning(push)) \
322 __pragma(warning(disable:4127)) \
323 while(0) \
324 __pragma(warning(pop))
325 #else
326 #define G_STMT_END while (0)
327 #endif
328 #endif
330 /* Deprecated -- do not use. */
331 #ifndef G_DISABLE_DEPRECATED
332 #ifdef G_DISABLE_CONST_RETURNS
333 #define G_CONST_RETURN
334 #else
335 #define G_CONST_RETURN const
336 #endif
337 #endif
340 * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to
341 * the compiler about the expected result of an expression. Some compilers
342 * can use this information for optimizations.
344 * The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when
345 * putting assignments in g_return_if_fail ().
347 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
348 #define _G_BOOLEAN_EXPR(expr) \
349 G_GNUC_EXTENSION ({ \
350 int _g_boolean_var_; \
351 if (expr) \
352 _g_boolean_var_ = 1; \
353 else \
354 _g_boolean_var_ = 0; \
355 _g_boolean_var_; \
357 #define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1))
358 #define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0))
359 #else
360 #define G_LIKELY(expr) (expr)
361 #define G_UNLIKELY(expr) (expr)
362 #endif
364 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
365 #define G_DEPRECATED __attribute__((__deprecated__))
366 #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
367 #define G_DEPRECATED __declspec(deprecated)
368 #else
369 #define G_DEPRECATED
370 #endif
372 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
373 #define G_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
374 #elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
375 #define G_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
376 #else
377 #define G_DEPRECATED_FOR(f) G_DEPRECATED
378 #endif
380 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
381 #define G_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available before " #maj "." #min)))
382 #elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
383 #define G_UNAVAILABLE(maj,min) __declspec(deprecated("is not available before " #maj "." #min))
384 #else
385 #define G_UNAVAILABLE(maj,min) G_DEPRECATED
386 #endif
388 #ifndef _GLIB_EXTERN
389 #define _GLIB_EXTERN extern
390 #endif
392 /* These macros are used to mark deprecated functions in GLib headers,
393 * and thus have to be exposed in installed headers. But please
394 * do *not* use them in other projects. Instead, use G_DEPRECATED
395 * or define your own wrappers around it.
398 #ifdef GLIB_DISABLE_DEPRECATION_WARNINGS
399 #define GLIB_DEPRECATED _GLIB_EXTERN
400 #define GLIB_DEPRECATED_FOR(f) _GLIB_EXTERN
401 #define GLIB_UNAVAILABLE(maj,min) _GLIB_EXTERN
402 #else
403 #define GLIB_DEPRECATED G_DEPRECATED _GLIB_EXTERN
404 #define GLIB_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _GLIB_EXTERN
405 #define GLIB_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _GLIB_EXTERN
406 #endif
408 #ifdef __GNUC__
410 /* these macros are private */
411 #define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName
412 #define _GLIB_AUTOPTR_TYPENAME(TypeName) TypeName##_autoptr
413 #define _GLIB_AUTO_FUNC_NAME(TypeName) glib_auto_cleanup_##TypeName
414 #define _GLIB_CLEANUP(func) __attribute__((cleanup(func)))
415 #define _GLIB_DEFINE_AUTOPTR_CHAINUP(ModuleObjName, ParentName) \
416 typedef ModuleObjName *_GLIB_AUTOPTR_TYPENAME(ModuleObjName); \
417 static inline void _GLIB_AUTOPTR_FUNC_NAME(ModuleObjName) (ModuleObjName **_ptr) { \
418 _GLIB_AUTOPTR_FUNC_NAME(ParentName) ((ParentName **) _ptr); } \
421 /* these macros are API */
422 #define G_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func) \
423 typedef TypeName *_GLIB_AUTOPTR_TYPENAME(TypeName); \
424 G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
425 static inline void _GLIB_AUTOPTR_FUNC_NAME(TypeName) (TypeName **_ptr) { if (*_ptr) (func) (*_ptr); } \
426 G_GNUC_END_IGNORE_DEPRECATIONS
427 #define G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func) \
428 G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
429 static inline void _GLIB_AUTO_FUNC_NAME(TypeName) (TypeName *_ptr) { (func) (_ptr); } \
430 G_GNUC_END_IGNORE_DEPRECATIONS
431 #define G_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none) \
432 G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
433 static inline void _GLIB_AUTO_FUNC_NAME(TypeName) (TypeName *_ptr) { if (*_ptr != none) (func) (*_ptr); } \
434 G_GNUC_END_IGNORE_DEPRECATIONS
435 #define g_autoptr(TypeName) _GLIB_CLEANUP(_GLIB_AUTOPTR_FUNC_NAME(TypeName)) _GLIB_AUTOPTR_TYPENAME(TypeName)
436 #define g_auto(TypeName) _GLIB_CLEANUP(_GLIB_AUTO_FUNC_NAME(TypeName)) TypeName
437 #define g_autofree _GLIB_CLEANUP(g_autoptr_cleanup_generic_gfree)
439 #else /* not GNU C */
440 /* this (dummy) macro is private */
441 #define _GLIB_DEFINE_AUTOPTR_CHAINUP(ModuleObjName, ParentName)
443 /* these (dummy) macros are API */
444 #define G_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, func)
445 #define G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(TypeName, func)
446 #define G_DEFINE_AUTO_CLEANUP_FREE_FUNC(TypeName, func, none)
448 /* no declaration of g_auto() or g_autoptr() here */
449 #endif
451 #endif /* __G_MACROS_H__ */