git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2] for_each_string_list_item: avoid undefined behavior for empty list

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 20, 2017, 05:40 UTC
Message-ID
<xmqqbmm6nd0v.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<20170920052705.GC126984@aiede.mtv.corp.google.com>
Jonathan Nieder <jrnieder@gmail.com> writes:
Show 11 quoted lines
> D. Eliminate for_each_string_list_item and let callers just do
>
> 	unsigned int i;
> 	for (i = 0; i < list->nr; i++) {
> 		struct string_list_item *item = list->items[i];
> 		...
> 	}
>
>    Having to declare item is unnecessarily verbose, decreasing the
>    appeal of this option.  I think I like it anyway, but I wasn't able
>    to convince coccinelle to do it.

When using the macro, item still needs to be declared outside by the user, so it's not all that unpleasant, though.

Show 9 quoted lines
> E. Use subtraction instead of addition:
>    #define for_each_string_list_item(item, list) \
>    	for (item = ...; \
> 	     (item == list->items ? 0 : item - list->items) < nr; \
> 	     item++)
>
>    I expected the compiler to figure out that this is a long way of writing
>    (item - list->items), but at least with gcc 4.8.4 -O2, no such
>    luck.  This generates uglier assembly than the NULL check.
Yuck.  You cannot easily unsee such an ugliness X-<.

The patch and explanation above --- looked quite nicely written. Will queue.

Thanks.
Show 17 quoted lines
> diff --git a/string-list.h b/string-list.h
> index 29bfb7ae45..79ae567cbc 100644
> --- a/string-list.h
> +++ b/string-list.h
> @@ -32,8 +32,10 @@ void string_list_clear_func(struct string_list *list, string_list_clear_func_t c
>  typedef int (*string_list_each_func_t)(struct string_list_item *, void *);
>  int for_each_string_list(struct string_list *list,
>  			 string_list_each_func_t, void *cb_data);
> -#define for_each_string_list_item(item,list) \
> -	for (item = (list)->items; item < (list)->items + (list)->nr; ++item)
> +#define for_each_string_list_item(item,list)            \
> +	for (item = (list)->items;                      \
> +	     item && item < (list)->items + (list)->nr; \
> +	     ++item)
>  
>  /*
>   * Apply want to each item in list, retaining only the ones for which
Previous: Jonathan NiederNext: Michael Haggerty
Message 13 of 29 in “for_each_string_list_item(): behave correctly for empty list”
  1. for_each_string_list_item(): behave correctly for empty listMichael Haggerty, Sep 15, 2017
  2. Jonathan NiederSep 15, 2017
  3. Michael HaggertySep 16, 2017
  4. SZEDER GáborSep 16, 2017
  5. Michael HaggertySep 17, 2017
  6. Kaartic SivaraamSep 19, 2017
  7. Junio C HamanoSep 20, 2017
  8. Jonathan NiederSep 20, 2017
  9. Junio C HamanoSep 20, 2017
  10. Jonathan NiederSep 20, 2017
  11. Junio C HamanoSep 20, 2017
  12. for_each_string_list_item: avoid undefined behavior for empty listJonathan Nieder, Sep 20, 2017
  13. Junio C HamanoSep 20, 2017
  14. Michael HaggertySep 20, 2017
  15. Kaartic SivaraamSep 20, 2017
  16. doc: camelCase the config variables to improve readabilityKaartic Sivaraam, Sep 20, 2017
  17. Andreas SchwabSep 20, 2017
  18. Jonathan NiederSep 20, 2017
  19. Andreas SchwabSep 20, 2017
  20. Junio C HamanoSep 21, 2017
  21. Andreas SchwabSep 21, 2017
  22. Kaartic SivaraamSep 20, 2017
  23. Junio C HamanoSep 17, 2017
  24. Michael HaggertySep 17, 2017
  25. Junio C HamanoSep 18, 2017
  26. Stefan BellerSep 19, 2017
  27. Michael HaggertySep 19, 2017
  28. SZEDER GáborSep 19, 2017
  29. SZEDER GáborSep 19, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.