mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
macros: Add a generic way to get and check the supported C standard
Try to get the value of __STDC_VERSION__ if supported, if not just fallback to the oldest standard that any compiler should handle.
This commit is contained in:
parent
14ba699508
commit
633561ada2
@ -411,6 +411,8 @@ G_GNUC_INTERNAL
|
|||||||
G_GNUC_MAY_ALIAS
|
G_GNUC_MAY_ALIAS
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
|
G_C_STD_VERSION
|
||||||
|
G_C_STD_CHECK_VERSION
|
||||||
G_CXX_STD_VERSION
|
G_CXX_STD_VERSION
|
||||||
G_CXX_STD_CHECK_VERSION
|
G_CXX_STD_CHECK_VERSION
|
||||||
|
|
||||||
|
45
glib/docs.c
45
glib/docs.c
@ -2527,6 +2527,47 @@
|
|||||||
* Since: 2.6
|
* Since: 2.6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_C_STD_VERSION:
|
||||||
|
*
|
||||||
|
* The C standard version the code is compiling against, it's normally
|
||||||
|
* defined with the same value of `__STDC_VERSION__` for C standard
|
||||||
|
* compatible compilers, while it uses the lowest standard version
|
||||||
|
* in pure MSVC, given that in such compiler the definition depends on
|
||||||
|
* a compilation flag.
|
||||||
|
*
|
||||||
|
* This is granted to be undefined when compiling with a C++ compiler.
|
||||||
|
*
|
||||||
|
* See also: %G_C_STD_CHECK_VERSION and %G_CXX_STD_VERSION
|
||||||
|
*
|
||||||
|
* Since: 2.76
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_C_STD_CHECK_VERSION:
|
||||||
|
* @version: The C version to be checked for compatibility
|
||||||
|
*
|
||||||
|
* Macro to check if the current compiler supports a specified @version
|
||||||
|
* of the C standard. Such value must be numeric and can be provided both
|
||||||
|
* in the short form for the well-known versions (e.g. `90`, `99`...) or in
|
||||||
|
* the complete form otherwise (e.g. `199000L`, `199901L`, `205503L`...).
|
||||||
|
*
|
||||||
|
* When a C++ compiler is used, the macro is defined and returns always %FALSE.
|
||||||
|
*
|
||||||
|
* This value is compared against %G_C_STD_VERSION.
|
||||||
|
*
|
||||||
|
* |[<!-- language="C" -->
|
||||||
|
* #if G_C_STD_CHECK_VERSION(17)
|
||||||
|
* #endif
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* See also: %G_CXX_STD_CHECK_VERSION
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if @version is supported by the compiler, %FALSE otherwise
|
||||||
|
*
|
||||||
|
* Since: 2.76
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G_CXX_STD_VERSION:
|
* G_CXX_STD_VERSION:
|
||||||
*
|
*
|
||||||
@ -2537,7 +2578,7 @@
|
|||||||
*
|
*
|
||||||
* This is granted to be undefined when not compiling with a C++ compiler.
|
* This is granted to be undefined when not compiling with a C++ compiler.
|
||||||
*
|
*
|
||||||
* See also: %G_CXX_STD_CHECK_VERSION
|
* See also: %G_CXX_STD_CHECK_VERSION and %G_C_STD_VERSION
|
||||||
*
|
*
|
||||||
* Since: 2.76
|
* Since: 2.76
|
||||||
*/
|
*/
|
||||||
@ -2560,6 +2601,8 @@
|
|||||||
* #endif
|
* #endif
|
||||||
* ]|
|
* ]|
|
||||||
*
|
*
|
||||||
|
* See also: %G_C_STD_CHECK_VERSION
|
||||||
|
*
|
||||||
* Returns: %TRUE if @version is supported by the compiler, %FALSE otherwise
|
* Returns: %TRUE if @version is supported by the compiler, %FALSE otherwise
|
||||||
*
|
*
|
||||||
* Since: 2.76
|
* Since: 2.76
|
||||||
|
@ -69,8 +69,26 @@
|
|||||||
# undef G_CXX_STD_VERSION
|
# undef G_CXX_STD_VERSION
|
||||||
# define G_CXX_STD_CHECK_VERSION(version) (0)
|
# define G_CXX_STD_CHECK_VERSION(version) (0)
|
||||||
|
|
||||||
|
# if defined (__STDC_VERSION__)
|
||||||
|
# define G_C_STD_VERSION __STDC_VERSION__
|
||||||
|
# else
|
||||||
|
# define G_C_STD_VERSION 199000L
|
||||||
|
# endif /* defined (__STDC_VERSION__) */
|
||||||
|
|
||||||
|
# define G_C_STD_CHECK_VERSION(version) ( \
|
||||||
|
((version) >= 199000L && (version) <= G_C_STD_VERSION) || \
|
||||||
|
((version) == 89 && G_C_STD_VERSION >= 199000L) || \
|
||||||
|
((version) == 90 && G_C_STD_VERSION >= 199000L) || \
|
||||||
|
((version) == 99 && G_C_STD_VERSION >= 199901L) || \
|
||||||
|
((version) == 11 && G_C_STD_VERSION >= 201112L) || \
|
||||||
|
((version) == 17 && G_C_STD_VERSION >= 201710L) || \
|
||||||
|
0)
|
||||||
|
|
||||||
#else /* defined (__cplusplus) */
|
#else /* defined (__cplusplus) */
|
||||||
|
|
||||||
|
# undef G_C_STD_VERSION
|
||||||
|
# define G_C_STD_CHECK_VERSION(version) (0)
|
||||||
|
|
||||||
# if defined (_MSVC_LANG)
|
# if defined (_MSVC_LANG)
|
||||||
# define G_CXX_STD_VERSION (_MSVC_LANG > __cplusplus ? _MSVC_LANG : __cplusplus)
|
# define G_CXX_STD_VERSION (_MSVC_LANG > __cplusplus ? _MSVC_LANG : __cplusplus)
|
||||||
# else
|
# else
|
||||||
|
@ -23,7 +23,12 @@
|
|||||||
#error G_CXX_STD_VERSION is not defined
|
#error G_CXX_STD_VERSION is not defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_C_STD_VERSION
|
||||||
|
#error G_C_STD_VERSION should be undefined in C programs
|
||||||
|
#endif
|
||||||
|
|
||||||
G_STATIC_ASSERT (G_CXX_STD_VERSION);
|
G_STATIC_ASSERT (G_CXX_STD_VERSION);
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (99));
|
||||||
|
|
||||||
#if G_CXX_STD_VERSION >= 199711L
|
#if G_CXX_STD_VERSION >= 199711L
|
||||||
G_STATIC_ASSERT (G_CXX_STD_CHECK_VERSION (98));
|
G_STATIC_ASSERT (G_CXX_STD_CHECK_VERSION (98));
|
||||||
|
@ -27,6 +27,81 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
G_STATIC_ASSERT (!G_CXX_STD_CHECK_VERSION (98));
|
G_STATIC_ASSERT (!G_CXX_STD_CHECK_VERSION (98));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (89));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (90));
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION >= 199000L
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (89));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (90));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (199000L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION == 198900L
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (99));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (199901L));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (11));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (201112L));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (17));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (201710L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION >= 199901L
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (99));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (199901L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION == 199901L
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (11));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (201112L));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (17));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (201710L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION >= 201112L
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (11));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (201112L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION == 201112L
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (17));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (201710L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION >= 201710L
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (17));
|
||||||
|
G_STATIC_ASSERT (G_C_STD_CHECK_VERSION (201710L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if G_C_STD_VERSION == 201710L
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (23));
|
||||||
|
G_STATIC_ASSERT (!G_C_STD_CHECK_VERSION (202300L));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _G_EXPECTED_C_STANDARD
|
||||||
|
static void
|
||||||
|
test_c_standard (void)
|
||||||
|
{
|
||||||
|
guint64 std_version = 0;
|
||||||
|
|
||||||
|
if (!g_ascii_string_to_unsigned (_G_EXPECTED_C_STANDARD, 10, 0, G_MAXUINT64,
|
||||||
|
&std_version, NULL))
|
||||||
|
{
|
||||||
|
g_test_skip ("Expected standard value is non-numeric: "
|
||||||
|
_G_EXPECTED_C_STANDARD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_true (G_C_STD_CHECK_VERSION (std_version));
|
||||||
|
|
||||||
|
if (std_version > 80 && std_version < 99)
|
||||||
|
std_version = 90;
|
||||||
|
|
||||||
|
if (std_version >= 90)
|
||||||
|
g_assert_cmpuint (G_C_STD_VERSION, >=, (std_version + 1900) * 100);
|
||||||
|
else
|
||||||
|
g_assert_cmpuint (G_C_STD_VERSION, >=, (std_version + 2000) * 100);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Test that G_STATIC_ASSERT_EXPR can be used as an expression */
|
/* Test that G_STATIC_ASSERT_EXPR can be used as an expression */
|
||||||
static void
|
static void
|
||||||
@ -71,6 +146,10 @@ main (int argc,
|
|||||||
{
|
{
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
#ifdef _G_EXPECTED_C_STANDARD
|
||||||
|
g_test_add_func ("/C/standard-" _G_EXPECTED_C_STANDARD, test_c_standard);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_test_add_func ("/alignof/fallback", test_alignof_fallback);
|
g_test_add_func ("/alignof/fallback", test_alignof_fallback);
|
||||||
g_test_add_func ("/assert/static", test_assert_static);
|
g_test_add_func ("/assert/static", test_assert_static);
|
||||||
g_test_add_func ("/struct/sizeof_member", test_struct_sizeof_member);
|
g_test_add_func ("/struct/sizeof_member", test_struct_sizeof_member);
|
||||||
|
@ -306,7 +306,10 @@ foreach test_name, extra_args : glib_tests
|
|||||||
'@0@-c-@1@'.format(test_name, std) : extra_args + {
|
'@0@-c-@1@'.format(test_name, std) : extra_args + {
|
||||||
'source' : extra_args.get('source', test_name + '.c'),
|
'source' : extra_args.get('source', test_name + '.c'),
|
||||||
'suite' : ['cc'] + extra_args.get('suite', []),
|
'suite' : ['cc'] + extra_args.get('suite', []),
|
||||||
'c_args' : [c_standards.get(std)] + extra_args.get('c_args', []),
|
'c_args' : [
|
||||||
|
c_standards.get(std),
|
||||||
|
'-D_G_EXPECTED_C_STANDARD="@0@"'.format(std)
|
||||||
|
] + extra_args.get('c_args', []),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endif
|
endif
|
||||||
|
Loading…
Reference in New Issue
Block a user