With this trick from CCAN (http://ccodearchive.net/info/array_size.html) we ensure at build-time user is indeed passing an array and not a pointer.
The code in CCAN uses several other macros like BUILD_ASSERT, BUILD_ASSERT_OR_ZERO. Since this is a public header, i think it's preferred not to export these other macros, unless there's interest in them. --- .gitignore | 1 + Makefile.am | 4 +++- ell/util.h | 4 +++- unit/test-util.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 unit/test-util.c diff --git a/.gitignore b/.gitignore index 81c83c7..01a9406 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ unit/test-netlink unit/test-dbus unit/test-dbus-message unit/test-array +unit/test-util doc/*.bak doc/*.stamp diff --git a/Makefile.am b/Makefile.am index e822cd8..37b1781 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,7 +61,7 @@ noinst_PROGRAMS = unit/test-unit unit/test-queue \ unit/test-plugin unit/test-checksum \ unit/test-settings unit/test-netlink \ unit/test-dbus unit/test-dbus-message \ - unit/test-array + unit/test-array unit/test-util unit_test_unit_LDADD = ell/libell-private.la @@ -91,6 +91,8 @@ unit_test_dbus_message_LDADD = ell/libell-private.la unit_test_array_LDADD = ell/libell-private.la +unit_test_util_LDADD = ell/libell-private.la + noinst_LTLIBRARIES += unit/example-plugin.la unit_example_plugin_la_LDFLAGS = -no-undefined -module -avoid-version \ diff --git a/ell/util.h b/ell/util.h index d7849c1..3c9b14f 100644 --- a/ell/util.h +++ b/ell/util.h @@ -52,7 +52,9 @@ do { \ __p->__v = (val); \ } while(0) -#define L_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define L_ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + \ + sizeof(char[1 - 2 * !!__builtin_types_compatible_p(typeof(x), \ + typeof(&(x)[0]))]) - 1) void *l_malloc(size_t size) __attribute__ ((warn_unused_result, malloc)); void l_free(void *ptr); diff --git a/unit/test-util.c b/unit/test-util.c new file mode 100644 index 0000000..ec7fecf --- /dev/null +++ b/unit/test-util.c @@ -0,0 +1,59 @@ +/* + * + * Embedded Linux library + * + * Copyright (C) 2011-2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <ell/ell.h> +#include <assert.h> + +static void array_size1(const void *data) +{ + const char dummy[20]; + + assert(L_ARRAY_SIZE(dummy) == 20); +} + +struct a { + int n; + const char *s; +}; + +static void array_size2(const void *data) +{ + struct a dummy[] = { + { 20, "test 1" }, + { 30, "test 2" } + }; + + assert(L_ARRAY_SIZE(dummy) == 2); +} + +int main(int argc, char *argv[]) +{ + l_test_init(&argc, &argv); + + l_test_add("array-size1", array_size1, NULL); + l_test_add("array-size2", array_size2, NULL); + + return l_test_run(); +} -- 1.7.10.2 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman