[PATCH 1/2] Add common macro for safely deriving the size of array

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This provides a simple ARRAY_SIZE() macro, which (given a good compiler)
will also break compile if you try to use it on a pointer. This can
ensure your code is robust to changes, without needing a gratuitous
macro or constant. Credits to Rusty Russell
(http://ccan.ozlabs.org/info/array_size.html)

Having a util.h file, this kind of things can be shared among all users
and we can remove all the declarations of ARRAY_SIZE.
---
 acinclude.m4 |   22 ++++++++++++++++++++++
 configure.ac |    1 +
 src/util.h   |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 0 deletions(-)
 create mode 100644 src/util.h

diff --git a/acinclude.m4 b/acinclude.m4
index a37959a..8c2ae92 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -31,6 +31,28 @@ AC_DEFUN([AC_FUNC_PPOLL], [
 			[Define to 1 if you need the ppoll() function.]))
 ])
 
+AC_DEFUN([AC_FUNC_TYPES_COMPATIBLE_P], [
+	AC_CACHE_CHECK([if compiler has __builtin_types_compatible_p function],
+		[cc_cv_func_types_compatible_p],
+		[ac_save_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS -Werror"
+		AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+			[int some_function();
+			int some_function() {
+			return __builtin_types_compatible_p(char *, int) ? 1 : 0;
+			}])],
+			[cc_cv_func_types_compatible_p=yes],
+			[cc_cv_func_types_compatible_p=no])
+		CFLAGS="$ac_save_CFLAGS"
+	])
+
+	AS_IF([test "x$cc_cv_func_types_compatible_p" = "xyes"],
+		[AC_DEFINE([SUPPORT__BUILTIN_TYPES_COMPATIBLE_P], 1,
+			[Define this if the compiler supports __builtin_types_compatible_p() function])
+			$1],
+		[$2])
+])
+
 AC_DEFUN([AC_INIT_BLUEZ], [
 	AC_PREFIX_DEFAULT(/usr/local)
 
diff --git a/configure.ac b/configure.ac
index 223c9d1..fed730f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,7 @@ AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 
 AC_FUNC_PPOLL
+AC_FUNC_TYPES_COMPATIBLE_P
 
 AC_CHECK_LIB(dl, dlopen, dummy=yes,
 			AC_MSG_ERROR(dynamic linking loader is required))
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..2c8a554
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,55 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2011  Texas Instruments, Inc.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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
+ *
+ */
+
+/**
+ * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
+ * @cond: the compile-time condition which must be true.
+ *
+ * Your compile will fail if the condition isn't true, or can't be evaluated
+ * by the compiler.  This can be used in an expression: its value is "0".
+ *
+ * Example:
+ *      #define foo_to_char(foo)                                            \
+ *              ((char *)(foo)                                              \
+ *              + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
+ */
+#define BUILD_ASSERT_OR_ZERO(cond) \
+	(sizeof(char [1 - 2*!(cond)]) - 1)
+
+#if SUPPORT__BUILTIN_TYPES_COMPATIBLE_P
+#define _array_size_chk(arr)						\
+	BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(arr), \
+							typeof(&(arr)[0])))
+#else
+#define _array_size_chk(arr) 0
+#endif
+
+/**
+ * ARRAY_SIZE - get the number of elements in a visible array
+ * @arr: the array whose size you want.
+ *
+ * This does not work on pointers, or arrays declared as [], or
+ * function parameters.  With correct compiler support, such usage
+ * will cause a build error (see build_assert).
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr))
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux