mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 05:56:14 +01:00
gmacros: Provide platform-independent G_ALWAYS_INLINE and G_NO_INLINE
We had gcc-only implementations for them while both can be used in all the supported platforms we have. So let's just provide generic definitions, while we keep the old ones for both consistency and retro-compatibility.
This commit is contained in:
parent
b5231ed003
commit
15cd0f0461
@ -516,6 +516,10 @@ G_CONST_RETURN
|
||||
G_NORETURN
|
||||
G_NORETURN_FUNCPTR
|
||||
|
||||
<SUBSECTION>
|
||||
G_ALWAYS_INLINE
|
||||
G_NO_INLINE
|
||||
|
||||
<SUBSECTION>
|
||||
G_N_ELEMENTS
|
||||
</SECTION>
|
||||
@ -782,6 +786,7 @@ g_macro__has_attribute
|
||||
g_macro__has_builtin
|
||||
g_macro__has_feature
|
||||
g_macro__has_extension
|
||||
g_macro__has_attribute___always_inline__
|
||||
g_macro__has_attribute___alloc_size__
|
||||
g_macro__has_attribute___const__
|
||||
g_macro__has_attribute___deprecated__
|
||||
|
@ -212,6 +212,9 @@
|
||||
* Declaring a function as `noinline` prevents the function from being
|
||||
* considered for inlining.
|
||||
*
|
||||
* This macro is provided for retro-compatibility and will be eventually
|
||||
* deprecated, but %G_NO_INLINE should be used instead.
|
||||
*
|
||||
* The attribute may be placed before the declaration or definition,
|
||||
* right before the `static` keyword.
|
||||
*
|
||||
@ -228,6 +231,8 @@
|
||||
* [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute)
|
||||
* for more details.
|
||||
*
|
||||
* See also: %G_NO_INLINE, %G_ALWAYS_INLINE.
|
||||
*
|
||||
* Since: 2.58
|
||||
*/
|
||||
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_58 because it’s
|
||||
@ -1069,6 +1074,100 @@
|
||||
GLIB_AVAILABLE_MACRO_IN_2_68
|
||||
#endif
|
||||
|
||||
/**
|
||||
* G_ALWAYS_INLINE:
|
||||
*
|
||||
* Expands to the GNU C `always_inline` or MSVC `__forceinline` function
|
||||
* attribute depending on the compiler. It is used for declaring functions
|
||||
* as always inlined, ignoring the compiler optimization levels.
|
||||
*
|
||||
* The attribute may be placed before the declaration or definition,
|
||||
* right before the `static` keyword.
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* G_ALWAYS_INLINE
|
||||
* static int
|
||||
* do_inline_this (void)
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* See the
|
||||
* [GNU C documentation](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute)
|
||||
* and the
|
||||
* [MSVC documentation](https://docs.microsoft.com/en-us/visualstudio/misc/inline-inline-forceinline)
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_74 because it’s
|
||||
* used within the GLib headers in function declarations which are always
|
||||
* evaluated when a header is included. This results in warnings in third party
|
||||
* code which includes glib.h, even if the third party code doesn’t use the new
|
||||
* macro itself. */
|
||||
#if g_macro__has_attribute(__always_inline__)
|
||||
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||
# define G_ALWAYS_INLINE [[gnu::always_inline]]
|
||||
# else
|
||||
# define G_ALWAYS_INLINE __attribute__ ((__always_inline__))
|
||||
# endif
|
||||
#elif defined (_MSC_VER)
|
||||
/* Use MSVC specific syntax. */
|
||||
# define G_ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
# define G_ALWAYS_INLINE /* empty */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* G_NO_INLINE:
|
||||
*
|
||||
* Expands to the GNU C or MSVC `noinline` function attribute
|
||||
* depending on the compiler. It is used for declaring functions
|
||||
* preventing from being considered for inlining.
|
||||
*
|
||||
* Note that %G_NO_INLINE supersedes the previous %G_GNUC_NO_INLINE
|
||||
* macro, which will eventually be deprecated.
|
||||
* %G_NO_INLINE supports more platforms.
|
||||
*
|
||||
* The attribute may be placed before the declaration or definition,
|
||||
* right before the `static` keyword.
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* G_NO_INLINE
|
||||
* static int
|
||||
* do_not_inline_this (void)
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* Since: 2.74
|
||||
*/
|
||||
/* Note: We can’t annotate this with GLIB_AVAILABLE_MACRO_IN_2_74 because it’s
|
||||
* used within the GLib headers in function declarations which are always
|
||||
* evaluated when a header is included. This results in warnings in third party
|
||||
* code which includes glib.h, even if the third party code doesn’t use the new
|
||||
* macro itself. */
|
||||
#if g_macro__has_attribute(__noinline__)
|
||||
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||
# define G_NO_INLINE [[gnu::noinline]]
|
||||
# else
|
||||
# define G_NO_INLINE __attribute__ ((__noinline__))
|
||||
# endif
|
||||
#elif defined (_MSC_VER) && (1200 <= _MSC_VER)
|
||||
/* Use MSVC specific syntax. */
|
||||
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||
/* Use ISO C++11 syntax when the compiler supports it. */
|
||||
# define G_NO_INLINE [[msvc::noinline]]
|
||||
# else
|
||||
# define G_NO_INLINE __declspec (noinline)
|
||||
# endif
|
||||
#else
|
||||
# define G_NO_INLINE /* empty */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The G_LIKELY and G_UNLIKELY macros let the programmer give hints to
|
||||
* the compiler about the expected result of an expression. Some compilers
|
||||
|
@ -158,6 +158,30 @@ test_atomic_int_exchange (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
G_NO_INLINE
|
||||
static gboolean
|
||||
do_not_inline_this (void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_ALWAYS_INLINE
|
||||
static inline gboolean
|
||||
do_inline_this (void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_inline_no_inline_macros (void)
|
||||
{
|
||||
g_test_message ("Test that G_NO_INLINE and G_ALWAYS_INLINE functions "
|
||||
"can be compiled with C++ compiler");
|
||||
|
||||
g_assert_false (do_not_inline_this ());
|
||||
g_assert_true (do_inline_this ());
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -174,6 +198,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/C++/atomic-int-compare-and-exchange-full", test_atomic_int_compare_and_exchange_full);
|
||||
g_test_add_func ("/C++/atomic-pointer-exchange", test_atomic_pointer_exchange);
|
||||
g_test_add_func ("/C++/atomic-int-exchange", test_atomic_int_exchange);
|
||||
g_test_add_func ("/C++/inlined-not-inlined-functions", test_inline_no_inline_macros);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user