mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 06:56: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
|
||||
|
||||
<SUBSECTION>
|
||||
G_C_STD_VERSION
|
||||
G_C_STD_CHECK_VERSION
|
||||
G_CXX_STD_VERSION
|
||||
G_CXX_STD_CHECK_VERSION
|
||||
|
||||
|
45
glib/docs.c
45
glib/docs.c
@ -2527,6 +2527,47 @@
|
||||
* 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:
|
||||
*
|
||||
@ -2537,7 +2578,7 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@ -2560,6 +2601,8 @@
|
||||
* #endif
|
||||
* ]|
|
||||
*
|
||||
* See also: %G_C_STD_CHECK_VERSION
|
||||
*
|
||||
* Returns: %TRUE if @version is supported by the compiler, %FALSE otherwise
|
||||
*
|
||||
* Since: 2.76
|
||||
|
@ -69,8 +69,26 @@
|
||||
# undef G_CXX_STD_VERSION
|
||||
# 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) */
|
||||
|
||||
# undef G_C_STD_VERSION
|
||||
# define G_C_STD_CHECK_VERSION(version) (0)
|
||||
|
||||
# if defined (_MSVC_LANG)
|
||||
# define G_CXX_STD_VERSION (_MSVC_LANG > __cplusplus ? _MSVC_LANG : __cplusplus)
|
||||
# else
|
||||
|
@ -23,7 +23,12 @@
|
||||
#error G_CXX_STD_VERSION is not defined
|
||||
#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_C_STD_CHECK_VERSION (99));
|
||||
|
||||
#if G_CXX_STD_VERSION >= 199711L
|
||||
G_STATIC_ASSERT (G_CXX_STD_CHECK_VERSION (98));
|
||||
|
@ -27,6 +27,81 @@
|
||||
#endif
|
||||
|
||||
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 */
|
||||
static void
|
||||
@ -71,6 +146,10 @@ main (int argc,
|
||||
{
|
||||
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 ("/assert/static", test_assert_static);
|
||||
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 + {
|
||||
'source' : extra_args.get('source', test_name + '.c'),
|
||||
'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
|
||||
|
Loading…
Reference in New Issue
Block a user