On Wed, Oct 02, 2013 at 12:34:53PM -0700, Ben Pfaff wrote:
> On Wed, Oct 02, 2013 at 02:40:09AM -0300, Flavio Leitner wrote:
> > GCC provides two useful builtin functions that can help
> > to improve array size checking during compilation.
> > 
> > This patch contains no functional changes, but it makes
> > it easier to detect mistakes.
> > 
> > Signed-off-by: Flavio Leitner <[email protected]>
> 
> This seems simpler:
> 
> --8<--------------------------cut here-------------------------->8--
> 
> From: Flavio Leitner <[email protected]>
> Date: Wed, 2 Oct 2013 02:40:09 -0300
> Subject: [PATCH] util: use gcc builtins to better check array sizes
> 
> GCC provides two useful builtin functions that can help
> to improve array size checking during compilation.
> 
> This patch contains no functional changes, but it makes
> it easier to detect mistakes.
> 
> Signed-off-by: Flavio Leitner <[email protected]>
> Signed-off-by: Ben Pfaff <[email protected]>
> ---
>  lib/util.h |   12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/util.h b/lib/util.h
> index 0db41be..8978bdb 100644
> --- a/lib/util.h
> +++ b/lib/util.h
> @@ -87,8 +87,18 @@ void ovs_assert_failure(const char *, const char *, const 
> char *) NO_RETURN;
>  
>  extern const char *program_name;
>  
> +#ifdef __GNUC__
> +/* Fails a build assertion if ARRAY is not an array type. */
> +#define ARRAY_CHECK(ARRAY) \
> +    BUILD_ASSERT(!__builtin_types_compatible_p(typeof(ARRAY),           \
> +                                               typeof(&ARRAY[0])))

I thought about using the BUILD_ASSERT(), but it doesn't seem to
work in all contexts that ARRAY_SIZE() is being used, so I wrote
those new macros.

Did it work for you? If so, in which branch? I am on master and it
breaks here:

gcc -DHAVE_CONFIG_H -I.   -I ./include -I ./lib -I ./lib
-Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith
-Wdeclaration-after-statement -Wswitch-enum -Wunused-parameter
-Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wmissing-prototypes
-Wmissing-field-initializers  -g -O2 -MT lib/ofp-util.o -MD -MP -MF
$depbase.Tpo -c -o lib/ofp-util.o lib/ofp-util.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from lib/hash.h:23:0,
                 from lib/flow.h:27,
                 from lib/classifier.h:105,
                 from lib/ofp-util.c:28:
lib/util.h:45:23: error: initializer element is not constant
         sizeof(struct { unsigned int build_assert_failed : (EXPR) ? 1 :
-1; })
                       ^
lib/util.h:48:35: note: in expansion of macro ‘BUILD_ASSERT__’
 #define BUILD_ASSERT(EXPR) (void) BUILD_ASSERT__(EXPR)
                                   ^
lib/util.h:93:5: note: in expansion of macro ‘BUILD_ASSERT’
     BUILD_ASSERT(!__builtin_types_compatible_p(typeof(ARRAY),
\
     ^
lib/util.h:101:6: note: in expansion of macro ‘ARRAY_CHECK’
     (ARRAY_CHECK(ARRAY), sizeof(ARRAY) / sizeof((ARRAY)[0]))
      ^
lib/ofp-util.c:657:40: note: in expansion of macro ‘ARRAY_SIZE’
 size_t ofputil_n_flow_dump_protocols =
ARRAY_SIZE(ofputil_flow_dump_protocols);

But the code looks correct.

The nice thing about using __builtin_choose_expr() is that
it doesn't evaluate the expression that was not chosen.

Thanks,
fbl

> +#else
> +#define ARRAY_CHECK(ARRAY) ((void) 0)
> +#endif
> +
>  /* Returns the number of elements in ARRAY. */
> -#define ARRAY_SIZE(ARRAY) (sizeof ARRAY / sizeof *ARRAY)
> +#define ARRAY_SIZE(ARRAY)                                       \
> +    (ARRAY_CHECK(ARRAY), sizeof(ARRAY) / sizeof((ARRAY)[0]))
>  
>  /* Returns X / Y, rounding up.  X must be nonnegative to round correctly. */
>  #define DIV_ROUND_UP(X, Y) (((X) + ((Y) - 1)) / (Y))
> -- 
> 1.7.10.4
> 
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to