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

Re: [PATCH v14 09/27] bisect--helper: `bisect_write` shell function in C

From
Pranit Bauva <pranit.bauva@gmail.com>
Date
Aug 30, 2016, 06:42 UTC
Message-ID
<CAFZEwPMz4n35x-g3cxM4KaADRJNmYmZBnwsDZD1wiiFPHJebew@mail.gmail.com>
In-Reply-To
<xmqqtwe5di02.fsf@gitster.mtv.corp.google.com>
Hey Junio,
On Sun, Aug 28, 2016 at 2:52 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 99 quoted lines
>
> Pranit Bauva <pranit.bauva@gmail.com> writes:
>
> >>> +struct bisect_terms {
> >>> +     struct strbuf term_good;
> >>> +     struct strbuf term_bad;
> >>> +};
> >>
> >> I think "struct strbuf" is overrated.  ...
> >> I think you can just say "const char *" in this case.
> >
> > Using struct strbuf is not really overrated but in fact required. But
>
> Nothing is required.
>
> I can make your life easier by requiring you to never use struct
> strbuf as a structure field type, though.  You will almost never
> need it unless you are building something exotic anyway.
>
> Step back and think what "strbuf" is good for.  It holds a pointer
> to a piece of memory the field owns, over-allocates and knows the
> size of allocation and usage.  That is good if you need to
>
>  (1) frequently find out the length of the string; without a
>      separate .len member you would have to run strlen().
>
>  (2) incrementally add to the string in-place; as it overallocates,
>      appending to the string would not have to involve realloc()
>      every time and the cost of it is amortized.
>
>  (3) make complex operations like splicing another string in,
>      trimming substring out, etc.
>
> You need to do none of the above to these fields.  term.term_good is
> either taken from an argv[] element, or you read from a line from a
> file and set it.  You may do some trivial computation and set it to
> the result, like "the other field uses 'old', so this one need to be
> set to 'new'".  The user of the field either has the string and sets
> it there, or reads the field's value as a whole string.  No string
> manipulation in the field in-place is needed.
>
> > yes, for this patch it might seem as overrated. In the shell code
> > initally TERM_GOOD is set to "good" while TERM_BAD is set to "bad".
> > Now there are a lot of instances (one of which is bisect_start()
> > function) where this can change. So if we keep it as "const char *",
> > it would be right to change the value of it after wards. And we cannot
> > keep it as "char []" because we don't know its size before hand.
>
> You are not making sense.  Nobody would suggest to use a fixed-size
> char array in this structure.  That wouldn't even work in the case
> where you are stuffing what comes in an argv[] element in there,
> e.g.
>
>     terms.term_good = argv[3];
>
> And you can of course support changing the value of the field
> without using strbuf.  Just update the pointer to point at the piece
> of memory that holds the new value.
>
> In short, I do not see any good reason why the term_good field has
> to be anything other than "char *term_good" or "const char *term_good".
>
> Now, what you need to consider choosing between the two depends on
> where these strings can come from.  If they are known to be always
> unchanging between the time you set it til the end of the program
> (e.g. using an element in argv[]), you can just assign without
> making any copy and you can use "const char *term_good".  All other
> cases, the structure needs to take the ownership, and you would need
> to make a copy if you don't have the ownership, e.g.
>
>         terms.term_good = xstrdup(argv[3]);
>
> You may be reading from a file, a line at a time and you may have a
> line's content in a strbuf.  You do not (yet) own the buffer after
> reading it, e.g.
>
>         strbuf_getline(&buf, fp);
>         terms.term_good = strbuf_detach(&buf, NULL);
>
> Of course, if you need to take ownership of the memory, you would
> need to free(3) it as needed, which means the pattern to set the
> field would become
>
>         free(terms.term_good);
>         terms.term_good = ... some new value ...;
>
> Using strbuf as a local variable is good.  It gives a higher level
> of abstraction when you are actually performing string operations.
> In most applications, however, a field in a struct is where the
> result of a step of computation is kept, not a scratch-pad to
> perform steps of computation in.  When you are ready to update the
> value of a field, you _have_ a completed string, and you can just
> use "char *" field to point at it.  There is no need for strbuf in
> the field.
>
> Don't look at the data structure used in trailer.[ch] as a model; it
> is an example of a terribly bad implementation taste, a pattern that
> should not be followed.  Print it, not read it and burn it as a good
> symbolic gesture.

Thanks for explaining when to use strbuf. I am convinced that the thing I am aiming for can be done with the help of "const char *". Though I will have to use strbuf in get_terms() and detach the string buffer from there as you have mentioned previously.

Regards, Pranit Bauva

Previous: Junio C HamanoNext: Pranit Bauva
Message 31 of 62 in “bisect--helper: use OPT_CMDMODE instead of OPT_BOOL”
  1. 01/27 bisect--helper: use OPT_CMDMODE instead of OPT_BOOLPranit Bauva, Aug 23, 2016
  2. 25/27 bisect--helper: retire `--bisect-autostart` subcommandPranit Bauva, Aug 23, 2016
  3. 13/27 bisect--helper: `bisect_start` shell function partially in CPranit Bauva, Aug 23, 2016
  4. Junio C HamanoAug 25, 2016
  5. Junio C HamanoAug 25, 2016
  6. Pranit BauvaAug 27, 2016
  7. Junio C HamanoAug 27, 2016
  8. 14/27 bisect--helper: `bisect_next` and `bisect_auto_next` shell function in CPranit Bauva, Aug 23, 2016
  9. Junio C HamanoAug 25, 2016
  10. Pranit BauvaAug 30, 2016
  11. Pranit BauvaAug 30, 2016
  12. Junio C HamanoAug 30, 2016
  13. Pranit BauvaAug 30, 2016
  14. 16/27 bisect--helper: retire `--next-all` subcommandPranit Bauva, Aug 23, 2016
  15. 06/27 wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()Pranit Bauva, Aug 23, 2016
  16. 27/27 bisect--helper: remove the dequote in bisect_start()Pranit Bauva, Aug 23, 2016
  17. 05/27 t6030: explicitly test for bisection cleanupPranit Bauva, Aug 23, 2016
  18. 19/27 bisect--helper: retire `--check-expected-revs` subcommandPranit Bauva, Aug 23, 2016
  19. 07/27 bisect--helper: `bisect_reset` shell function in CPranit Bauva, Aug 23, 2016
  20. Junio C HamanoAug 24, 2016
  21. Pranit BauvaAug 26, 2016
  22. Junio C HamanoAug 26, 2016
  23. Pranit BauvaAug 27, 2016
  24. Junio C HamanoAug 29, 2016
  25. 15/27 bisect--helper: retire `--bisect-clean-state` subcommandPranit Bauva, Aug 23, 2016
  26. Junio C HamanoAug 26, 2016
  27. 09/27 bisect--helper: `bisect_write` shell function in CPranit Bauva, Aug 23, 2016
  28. Junio C HamanoAug 24, 2016
  29. Pranit BauvaAug 27, 2016
  30. Junio C HamanoAug 27, 2016
  31. Pranit BauvaAug 30, 2016
  32. 18/27 bisect--helper: `bisect_state` & `bisect_head` shell function in CPranit Bauva, Aug 23, 2016
  33. 21/27 bisect--helper: `bisect_log` shell function in CPranit Bauva, Aug 23, 2016
  34. Junio C HamanoAug 26, 2016
  35. Pranit BauvaAug 27, 2016
  36. 24/27 bisect--helper: retire `--check-and-set-terms` subcommandPranit Bauva, Aug 23, 2016
  37. 17/27 bisect--helper: `bisect_autostart` shell function in CPranit Bauva, Aug 23, 2016
  38. Junio C HamanoAug 26, 2016
  39. 12/27 bisect--helper: `get_terms` & `bisect_terms` shell function in CPranit Bauva, Aug 23, 2016
  40. Junio C HamanoAug 25, 2016
  41. Pranit BauvaAug 27, 2016
  42. Junio C HamanoAug 29, 2016
  43. 04/27 bisect--helper: `bisect_clean_state` shell function in CPranit Bauva, Aug 23, 2016
  44. Junio C HamanoAug 24, 2016
  45. 20/27 bisect--helper: retire `--write-terms` subcommandPranit Bauva, Aug 23, 2016
  46. 23/27 bisect--helper: retire `--bisect-write` subcommandPranit Bauva, Aug 23, 2016
  47. 10/27 bisect--helper: `check_and_set_terms` shell function in CPranit Bauva, Aug 23, 2016
  48. 03/27 bisect--helper: `write_terms` shell function in CPranit Bauva, Aug 23, 2016
  49. 26/27 bisect--helper: retire `--bisect-auto-next` subcommandPranit Bauva, Aug 23, 2016
  50. 02/27 bisect: rewrite `check_term_format` shell function in CPranit Bauva, Aug 23, 2016
  51. 08/27 bisect--helper: `is_expected_rev` & `check_expected_revs` shell function in CPranit Bauva, Aug 23, 2016
  52. Junio C HamanoAug 24, 2016
  53. Pranit BauvaAug 27, 2016
  54. Junio C HamanoAug 29, 2016
  55. 22/27 bisect--helper: `bisect_replay` shell function in CPranit Bauva, Aug 23, 2016
  56. Junio C HamanoAug 26, 2016
  57. 11/27 bisect--helper: `bisect_next_check` & bisect_voc shell function in CPranit Bauva, Aug 23, 2016
  58. Junio C HamanoAug 24, 2016
  59. Pranit BauvaAug 27, 2016
  60. Pranit BauvaAug 23, 2016
  61. Junio C HamanoAug 23, 2016
  62. Pranit BauvaAug 23, 2016

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.