If you pass a newly-initialized or newly-cleared `string_list` to `for_each_string_list_item()`, then the latter does for ( item = (list)->items; /* note, this is NULL */ item < (list)->items + (list)->nr; /* note: NULL + 0 */ ++item) Even though this probably works almost everywhere, it is undefined behavior, and it could plausibly cause highly-optimizing compilers to misbehave. It would be a pain to have to change the signature of this macro, and we'd prefer not to add overhead to each iteration of the loop. So instead, whenever `list->items` is NULL, initialize `item` to point at a dummy `string_list_item` created for the purpose. This problem was noticed by Coverity. Signed-off-by: Michael Haggerty <mhagger@xxxxxxxxxxxx> --- Just a little thing I noticed in a Coverity report. This macro has been broken since it was first introduced, in 2010. This patch applies against maint. It is also available from my Git fork [1] as branch `iter-empty-string-list`. Michael [1] https://github.com/mhagger/git string-list.c | 2 ++ string-list.h | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/string-list.c b/string-list.c index 806b4c8723..7eacf6037f 100644 --- a/string-list.c +++ b/string-list.c @@ -1,6 +1,8 @@ #include "cache.h" #include "string-list.h" +struct string_list_item dummy_string_list_item; + void string_list_init(struct string_list *list, int strdup_strings) { memset(list, 0, sizeof(*list)); diff --git a/string-list.h b/string-list.h index 29bfb7ae45..79bb78d80a 100644 --- a/string-list.h +++ b/string-list.h @@ -32,8 +32,11 @@ 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) +extern struct string_list_item dummy_string_list_item; +#define for_each_string_list_item(item,list) \ + for (item = (list)->items ? (list)->items : &dummy_string_list_item; \ + item < (list)->items + (list)->nr; \ + ++item) /* * Apply want to each item in list, retaining only the ones for which -- 2.14.1