Re: [PATCH 1/5] trailer: separate public from internal portion of trailer_iterator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/08/2023 22:16, Glen Choo wrote:
As someone who isn't that familiar with trailer code, and will have less
time for the ML soon, this is more of a quick drive-by..

This is a bit of a drive-by comment as well ...

"Linus Arver via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes:

+#define private __private_to_trailer_c__do_not_use
+
  void trailer_iterator_init(struct trailer_iterator *iter, const char *msg)
  {
  	struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
  	strbuf_init(&iter->key, 0);
  	strbuf_init(&iter->val, 0);
  	opts.no_divider = 1;
-	trailer_info_get(&iter->info, msg, &opts);
-	iter->cur = 0;
+	trailer_info_get(&iter->private.info, msg, &opts);
+	iter->private.cur = 0;
  }
--- a/trailer.h
+++ b/trailer.h
@@ -119,8 +119,10 @@ struct trailer_iterator {
  	struct strbuf val;
...
  	/* private */
-	struct trailer_info info;
-	size_t cur;
+	struct {
+		struct trailer_info info;
+		size_t cur;
+	} __private_to_trailer_c__do_not_use;
  };

Interesting approach to "private members". I like that it's fairly
lightweight and clear. On the other hand, I think this will fail to
autocomplete on most people's development setups, and I don't think this
is worth the tradeoff.

This is the first instance of this I could find in the codebase.

We have something similar in unpack_trees.h see 576de3d9560 (unpack_trees: start splitting internal fields from public API, 2023-02-27). That adds an "internal" member to "sturct unpack_trees" of type "struct unpack_trees_internal which seems to be a easier naming scheme.

I'm not
really opposed to having a new way of doing things, but it would be nice
for us to be consistent with how we handle private members. Other
approaches I've seen are:

- Using a "larger" struct to hold private members and "downcasting" for
   public users (struct dir_iterator and struct dir_iterator_int). I
   dislike this because I think this enables 'wrong' memory access too
   easily.

   (As an aside, if we really wanted to 'strictly' enforce privateness in
   this patch, shouldn't we move the "#define private" into the .c file,
   the way dir_iterator_int is in the .c file?)

That #define is pretty ugly

Another common scheme is to have an opaque pointer to the private struct in the public struct (aka pimpl idiom). The merge machinery uses this - see merge-recursive.h. (I'm working on something similar for the sequencer so we can change the internals without having to re-compile everything that includes "sequencer.h")

- Prefixing private members with "__" (khash.h and other header-only
   libraries use this at least, not sure if we have this in the 'main
   tree'). I think this works pretty well most of the time.

It is common but I think the C standard reserves names beginning with "__"

- Just marking private members with a comment. IMO this is good enough
   the vast majority of the time - if something is private for a good
   reason, it's unlikely to get used accidentally anyway. But properly
   enforcing "privateness" is worthy goal anyway.

Personally, I think a decent tradeoff between enforcement and ergonomics
would be to use an inner struct like you do here, but name it something
autocomplete-friendly and obviously private, like "private" or
"_private".

I agree, something like that would match the unpack_trees example

I suspect self-regulation and code review should be enough
to catch nearly all accidental uses of private members.

Agreed

Best Wishes

Phillip




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux