From: Junio C Hamano <gitster@pobox.com>
To: Phillip Wood <phillip.wood123@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] strbuf: add compound literal test balloon
Date: Mon, 14 Jul 2025 07:26:55 -0700 [thread overview]
Message-ID: <xmqqa556x2z4.fsf@gitster.g> (raw)
In-Reply-To: <7ac55a5096c261b706f47ca239c381f71db2b67a.1752499653.git.phillip.wood@dunelm.org.uk> (Phillip Wood's message of "Mon, 14 Jul 2025 14:27:37 +0100")
Phillip Wood <phillip.wood123@gmail.com> writes:
> From: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> A C99 compound literal creates an unnamed object whose value is given by
> an initializer list. This allows us to simplify code where we cannot use
> a designated initalizer because the values of some members of the object
> need to be calculated first. For example this code from builtin/rebase.c
>
> struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
> struct reset_head_opts ropts = { 0 };
> int ret;
>
> strbuf_addf(&branch_reflog, "%s (finish): %s onto %s",
> opts->reflog_action,
> opts->head_name, oid_to_hex(&opts->onto->object.oid));
> strbuf_addf(&head_reflog, "%s (finish): returning to %s",
> opts->reflog_action, opts->head_name);
> ropts.branch = opts->head_name;
> ropts.flags = RESET_HEAD_REFS_ONLY;
> ropts.branch_msg = branch_reflog.buf;
> ropts.head_msg = head_reflog.buf;
> ret = reset_head(the_repository, &ropts);
>
> can be be simplified to
>
> struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
> int ret;
>
> strbuf_addf(&branch_reflog, "%s (finish): %s onto %s",
> opts->reflog_action,
> opts->head_name, oid_to_hex(&opts->onto->object.oid));
> strbuf_addf(&head_reflog, "%s (finish): returning to %s",
> opts->reflog_action, opts->head_name);
> ret = reset_head(the_repository, &(struct reset_head_opts) {
> .branch = opts->head_name,
> .flags = RESET_HEAD_REFS_ONLY,
> .branch_msg = branch_reflog.buf,
> .head_msg = head_reflog.buf,
> });
>
> The result is more readable as one can see the value of each member
> of the object being passed to the function at the call site rather
> than building the object piecemeal in the preceding lines.
Hmph, is it simpler, I have to wonder, in other words, I doubt you
simplified the code.
One thing the above rewrite did is to make it clear to readers that
the struct instance is used just once and then immediately got
discarded. As long as the object that gets passed this way does not
hold resources that need to be discarded itself (in other words,
does not require a call to reset_head_opts_release()), it makes the
code easier to follow.
But once the struct gains members that need to be released, I am not
sure if this construct does not make it harder to spot leaks.
Somebody who adds a member to _release() to the struct presumably
audits and find all places that need to call _release(), but among
them they find this place---now what? They need to first convert it
to the old fashioned way and then call _release() after the
reset_head() call returns, I guess.
I am not arguing against all uses of literals---I am just
anticipating future fallouts of encouraging overuse of this pattern,
and preparing what we would say when somebody adds a new use to
inappropriate places. Simple cases like the initialier should be
fine.
> strbuf.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/strbuf.c b/strbuf.c
> index f30fdc69843..c93c1208c93 100644
> --- a/strbuf.c
> +++ b/strbuf.c
> @@ -68,8 +68,7 @@ char strbuf_slopbuf[1];
>
> void strbuf_init(struct strbuf *sb, size_t hint)
> {
> - struct strbuf blank = STRBUF_INIT;
> - memcpy(sb, &blank, sizeof(*sb));
We should mark this clearly as a weather-balloon so that people do
not copy and paste it to elsewhere not just yet, shouldn't we? If
it proliferates everywhere and then later we discover that some
vintage of compiler on a platform we still care about miscompiles
the construct, we want to keep it simpler to revert.
> + *sb = (struct strbuf) STRBUF_INIT;
> if (hint)
> strbuf_grow(sb, hint);
> }
Other than that, thanks for taking an initiative.
next prev parent reply other threads:[~2025-07-14 14:26 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-14 13:27 [PATCH] strbuf: add compound literal test balloon Phillip Wood
2025-07-14 14:26 ` Junio C Hamano [this message]
2025-07-15 8:53 ` Patrick Steinhardt
2025-07-15 9:44 ` Phillip Wood
2025-07-15 16:24 ` Junio C Hamano
2025-07-16 14:29 ` Phillip Wood
2025-07-23 18:01 ` Junio C Hamano
2025-07-23 19:31 ` [PATCH] CodingGuidelines: document test balloons in flight Junio C Hamano
2025-07-24 6:55 ` Patrick Steinhardt
2025-07-24 16:39 ` Junio C Hamano
2025-07-24 16:55 ` Collin Funk
2025-07-26 23:15 ` Junio C Hamano
2025-07-24 14:26 ` Phillip Wood
2025-07-24 16:23 ` Junio C Hamano
2025-07-16 14:32 ` [PATCH] strbuf: add compound literal test balloon Phillip Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqa556x2z4.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood123@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).