On 2/16/22 15:27, Adrian Moreno wrote:
> Multi-variable loop iterators avoid potential undefined behavior by
> using an internal iterator variable to perform the iteration and only
> referencing the containing object (via OBJECT_CONTAINING) if the
> iterator has been validated via the second expression of the for
> statement.
> 
> That way, the user can easily implement a loop that never tries to
> obtain the object containing NULL or stack-allocated non-contained
> nodes.
> 
> When the loop ends normally (not via "break;") the user-provided
> variable is set to NULL.
> 
> Signed-off-by: Adrian Moreno <amore...@redhat.com>
> ---

Hi Adrian,

It feels a bit weird that these new macros are not used anywhere yet
(until we apply the next patches in the series).  On the other hand I
don't think it's easy to split the series otherwise so, with a small nit
below:

Acked-by: Dumitru Ceara <dce...@redhat.com>

Thanks,
Dumitru

>  include/openvswitch/util.h | 44 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/include/openvswitch/util.h b/include/openvswitch/util.h
> index 228b185c3..9c09e8aea 100644
> --- a/include/openvswitch/util.h
> +++ b/include/openvswitch/util.h
> @@ -145,6 +145,50 @@ OVS_NO_RETURN void ovs_assert_failure(const char *, 
> const char *, const char *);
>  #define INIT_CONTAINER(OBJECT, POINTER, MEMBER) \
>      ((OBJECT) = NULL, ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER))
>  
> +

Nit: We don't need this extra line.

> +/* Multi-variable container iterators.
> + *
> + * The following macros facilitate safe iteration over data structures
> + * contained in objects. It does so by using an internal iterator variable of
> + * the type of the member object pointer (i.e: pointer to the data 
> structure).
> + */
> +
> +/* Multi-variable iterator variable name.
> + * Returns the name of the internal iterator variable.
> + */
> +#define ITER_VAR(NAME) NAME ## __iterator__
> +
> +/* Multi-variable initialization. Creates an internal iterator variable that
> + * points to the provided pointer. The type of the iterator variable is
> + * ITER_TYPE*. It must be the same type as &VAR->MEMBER.
> + *
> + * The _EXP version evaluates the extra expressions once.
> + */
> +#define INIT_MULTIVAR(VAR, MEMBER, POINTER, ITER_TYPE)                  \
> +    INIT_MULTIVAR_EXP(VAR, MEMBER, POINTER, ITER_TYPE, (void) 0)
> +
> +#define INIT_MULTIVAR_EXP(VAR, MEMBER, POINTER, ITER_TYPE, ...)         \
> +    ITER_TYPE *ITER_VAR(VAR) = ( __VA_ARGS__ , (ITER_TYPE *) POINTER)
> +
> +/* Multi-variable condition.
> + * Evaluates the condition expression (that must be based on the internal
> + * iterator variable). Only if the result of expression is true, the OBJECT 
> is
> + * set to the object containing the current value of the iterator variable.
> + *
> + * It is up to the caller to make sure it is safe to run OBJECT_CONTAINING on
> + * the pointers that verify the condition.
> + */
> +#define CONDITION_MULTIVAR(VAR, MEMBER, EXPR)                                
>  \
> +    ((EXPR) ?                                                                
>  \
> +     (((VAR) = OBJECT_CONTAINING(ITER_VAR(VAR), VAR, MEMBER)), 1) :          
>  \
> +     (((VAR) = NULL), 0))
> +
> +/* Multi-variable update.
> + * Evaluates the expresssion that is supposed to update the iterator 
> variable.
> + */
> +#define UPDATE_MULTIVAR(VAR, EXPR)                                           
>  \
> +    ((EXPR), (VAR) = NULL)
> +
>  /* Returns the number of elements in ARRAY. */
>  #define ARRAY_SIZE(ARRAY) __ARRAY_SIZE(ARRAY)
>  

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to