On Mon, Jun 04, 2018 at 12:44:15PM +0900, Junio C Hamano wrote: > >> diff --git a/sequencer.c b/sequencer.c > >> index b98690ecd41..aba03e9429a 100644 > >> --- a/sequencer.c > >> +++ b/sequencer.c > >> @@ -175,6 +175,7 @@ static int git_sequencer_config(const char *k, const char *v, void *cb) > >> warning(_("invalid commit message cleanup mode '%s'"), > >> s); > >> > >> + free(s); > >> return status; > >> } > > > > Shouldn't 's' now lose 'const'? After all, git_config_string() > > gives you an allocated memory so... > > Yikes. Should git_config_string() and git_config_pathname() take > "char **dst" instead of "const char **" as their out-location > parameter? They both assign a pointer to an allocated piece of > memory for the caller to own or dispose of, but because of > const-ness of the pointee their first parameter has, a caller like > this one must declare "const char *s" yet is forced to call free() > not to leak the value when it is done. I've looked into it before, but that causes its own wave of headaches. The source of the problem is that we do: const char *some_var = "default"; ... git_config_string(&some_var, ...); So sometimes some_var needs to be freed and sometimes not (and every one of those uses is a potential leak, but it's OK because they're all program-lifetime globals anyway, and people don't _tend_ to set the same option over and over, leaking heap memory). And C being C, we can't convert a pointer-to-pointer-to-const into a pointer-to-pointer without an explicit cast. Doing it "right" in C would probably involve two variables: const char *some_var = "default"; const char *some_var_storage = NULL; int git_config_string_smart(const char **ptr, char **storage, const char *var, const char *value) { ... free(*storage); *ptr = *storage = xstrdup(value); return 0; } #define GIT_CONFIG_STRING(name, var, value) \ git_config_string_smart(&(name), &(name##_storage), var, value) Or something like that. We could also get away from an out-parameter and use the return type, since the single-pointer conversion is OK. But the primary value of git_config_string() is that it lets you return the error code as a one-liner. -Peff