From fd61a21ecdbbef5c1cf65d989ea42f4fc70b9b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 20 Jan 2020 16:41:34 +0400 Subject: [PATCH] Add and use G_SIZEOF_MEMBER() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A convenient macro present in the Linux kernel, named FIELD_SIZE() there. Signed-off-by: Marc-André Lureau --- docs/reference/glib/glib-sections.txt | 1 + gio/glocalfileoutputstream.c | 4 ++-- gio/gunixoutputstream.c | 4 ++-- gio/gunixsocketaddress.c | 2 +- glib/gmacros.h | 14 ++++++++++++++ glib/tests/macros.c | 8 ++++++++ 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index dd5f923f3..63f40baf5 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -424,6 +424,7 @@ CLAMP G_APPROX_VALUE +G_SIZEOF_MEMBER G_STRUCT_MEMBER G_STRUCT_MEMBER_P G_STRUCT_OFFSET diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c index a7bcb04a6..a8161bd52 100644 --- a/gio/glocalfileoutputstream.c +++ b/gio/glocalfileoutputstream.c @@ -224,9 +224,9 @@ g_local_file_output_stream_write (GOutputStream *stream, #ifdef G_OS_UNIX /* Macro to check if struct iovec and GOutputVector have the same ABI */ #define G_OUTPUT_VECTOR_IS_IOVEC (sizeof (struct iovec) == sizeof (GOutputVector) && \ - sizeof ((struct iovec *) 0)->iov_base == sizeof ((GOutputVector *) 0)->buffer && \ + G_SIZEOF_MEMBER (struct iovec, iov_base) == G_SIZEOF_MEMBER (GOutputVector, buffer) && \ G_STRUCT_OFFSET (struct iovec, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) && \ - sizeof ((struct iovec *) 0)->iov_len == sizeof((GOutputVector *) 0)->size && \ + G_SIZEOF_MEMBER (struct iovec, iov_len) == G_SIZEOF_MEMBER (GOutputVector, size) && \ G_STRUCT_OFFSET (struct iovec, iov_len) == G_STRUCT_OFFSET (GOutputVector, size)) static gboolean diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c index 506e09a8c..1af0b44d2 100644 --- a/gio/gunixoutputstream.c +++ b/gio/gunixoutputstream.c @@ -403,9 +403,9 @@ g_unix_output_stream_write (GOutputStream *stream, /* Macro to check if struct iovec and GOutputVector have the same ABI */ #define G_OUTPUT_VECTOR_IS_IOVEC (sizeof (struct iovec) == sizeof (GOutputVector) && \ - sizeof ((struct iovec *) 0)->iov_base == sizeof ((GOutputVector *) 0)->buffer && \ + G_SIZEOF_MEMBER (struct iovec, iov_base) == G_SIZEOF_MEMBER (GOutputVector, buffer) && \ G_STRUCT_OFFSET (struct iovec, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) && \ - sizeof ((struct iovec *) 0)->iov_len == sizeof((GOutputVector *) 0)->size && \ + G_SIZEOF_MEMBER (struct iovec, iov_len) == G_SIZEOF_MEMBER (GOutputVector, size) && \ G_STRUCT_OFFSET (struct iovec, iov_len) == G_STRUCT_OFFSET (GOutputVector, size)) static gboolean diff --git a/gio/gunixsocketaddress.c b/gio/gunixsocketaddress.c index 27e195e47..0ab1a62e9 100644 --- a/gio/gunixsocketaddress.c +++ b/gio/gunixsocketaddress.c @@ -67,7 +67,7 @@ enum }; #ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX sizeof (((struct sockaddr_un *) 0)->sun_path) +#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path) #endif struct _GUnixSocketAddressPrivate diff --git a/glib/gmacros.h b/glib/gmacros.h index e829f207b..d9c7906cd 100644 --- a/glib/gmacros.h +++ b/glib/gmacros.h @@ -1096,4 +1096,18 @@ #endif /* __GI_SCANNER__ */ +/** + * G_SIZEOF_MEMBER: + * @struct_type: a structure type, e.g. #GOutputVector + * @member: a field in the structure, e.g. `size` + * + * Returns: the size of @member in the struct definition without having a + * declared instance of @struct_type. + * + * Since: 2.64 + */ +#define G_SIZEOF_MEMBER(struct_type, member) \ + GLIB_AVAILABLE_MACRO_IN_2_64 \ + sizeof (((struct_type *) 0)->member) + #endif /* __G_MACROS_H__ */ diff --git a/glib/tests/macros.c b/glib/tests/macros.c index 89a1322ee..317832a41 100644 --- a/glib/tests/macros.c +++ b/glib/tests/macros.c @@ -50,6 +50,13 @@ test_alignof_fallback (void) check_alignof (struct { char a; int b; }); } +static void +test_struct_sizeof_member (void) +{ + G_STATIC_ASSERT (G_SIZEOF_MEMBER (struct { char a; int b; }, a) == sizeof (char)); + g_assert_cmpint (G_SIZEOF_MEMBER (struct { char a; int b; }, b), ==, sizeof (int)); +} + int main (int argc, char *argv[]) @@ -58,6 +65,7 @@ main (int argc, 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); return g_test_run (); }