On Fri, Mar 10, 2017 at 01:14:16AM +0100, René Scharfe wrote: > > 2. Ones which just copy a single object, like: > > > > memcpy(&dst, &src, sizeof(dst)); > > > > Perhaps we should be using struct assignment like: > > > > dst = src; > > > > here. It's safer and it should give the compiler more room to > > optimize. The only downside is that if you have pointers, it is > > easy to write "dst = src" when you meant "*dst = *src". > > Compilers can usually inline memcpy(3) calls, but assignments are > shorter and more pleasing to the eye, and we get a type check for > free. How about this? Yeah, I mostly wasn't sure how people felt about "shorter and more pleasing". It _is_ shorter and there's less to get wrong. But the memcpy() screams "hey, I am making a copy" and is idiomatic to at least a certain generation of C programmers. I guess something like COPY(dst, src) removes the part that you can get wrong, while still screaming copy. It's not idiomatic either, but at least it stands out. I dunno. > diff --git a/contrib/coccinelle/copy.cocci b/contrib/coccinelle/copy.cocci > new file mode 100644 > index 0000000000..f0d883932a > --- /dev/null > +++ b/contrib/coccinelle/copy.cocci > @@ -0,0 +1,31 @@ > +@@ > +type T; > +T dst; > +T src; > [...] > +type T; > +T dst; > +T *src; I think this misses the other two cases: (*dst, src) and (*dst, *src). Perhaps squash this in? --- builtin/blame.c | 2 +- builtin/pack-redundant.c | 4 ++-- contrib/coccinelle/copy.cocci | 32 ++++++++++++++++++++++++++++++++ diff.c | 4 ++-- dir.c | 2 +- fast-import.c | 6 +++--- line-log.c | 2 +- 7 files changed, 42 insertions(+), 10 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index f7aa95f4b..d0d917b37 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -680,7 +680,7 @@ static void dup_entry(struct blame_entry ***queue, { origin_incref(src->suspect); origin_decref(dst->suspect); - memcpy(dst, src, sizeof(*src)); + *dst = *src; dst->next = **queue; **queue = dst; *queue = &dst->next; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 72c815844..ac1d8111e 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -207,7 +207,7 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl, struct pack_list *entry) { struct pack_list *p = xmalloc(sizeof(struct pack_list)); - memcpy(p, entry, sizeof(struct pack_list)); + *p = *entry; p->next = *pl; *pl = p; return p; @@ -451,7 +451,7 @@ static void minimize(struct pack_list **min) while (perm) { if (is_superset(perm->pl, missing)) { new_perm = xmalloc(sizeof(struct pll)); - memcpy(new_perm, perm, sizeof(struct pll)); + *new_perm = *perm; new_perm->next = perm_ok; perm_ok = new_perm; } diff --git a/contrib/coccinelle/copy.cocci b/contrib/coccinelle/copy.cocci index f0d883932..da9969c84 100644 --- a/contrib/coccinelle/copy.cocci +++ b/contrib/coccinelle/copy.cocci @@ -29,3 +29,35 @@ T *src; - memcpy(&dst, src, sizeof(T)); + dst = *src; ) + +@@ +type T; +T *dst; +T src; +@@ +( +- memcpy(dst, &src, sizeof(*dst)); ++ *dst = src; +| +- memcpy(dst, &src, sizeof(src)); ++ *dst = src; +| +- memcpy(dst, &src, sizeof(T)); ++ *dst = src; +) + +@@ +type T; +T *dst; +T *src; +@@ +( +- memcpy(dst, src, sizeof(*dst)); ++ *dst = *src; +| +- memcpy(dst, src, sizeof(*src)); ++ *dst = *src; +| +- memcpy(dst, src, sizeof(T)); ++ *dst = *src; +) diff --git a/diff.c b/diff.c index 051761be4..fbd68ecd0 100644 --- a/diff.c +++ b/diff.c @@ -1169,7 +1169,7 @@ static void init_diff_words_data(struct emit_callback *ecbdata, { int i; struct diff_options *o = xmalloc(sizeof(struct diff_options)); - memcpy(o, orig_opts, sizeof(struct diff_options)); + *o = *orig_opts; ecbdata->diff_words = xcalloc(1, sizeof(struct diff_words_data)); @@ -3359,7 +3359,7 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) void diff_setup(struct diff_options *options) { - memcpy(options, &default_diff_options, sizeof(*options)); + *options = default_diff_options; options->file = stdout; diff --git a/dir.c b/dir.c index 4541f9e14..d3d0039bf 100644 --- a/dir.c +++ b/dir.c @@ -2499,7 +2499,7 @@ static int read_one_dir(struct untracked_cache_dir **untracked_, if (next > rd->end) return -1; *untracked_ = untracked = xmalloc(st_add(sizeof(*untracked), len)); - memcpy(untracked, &ud, sizeof(ud)); + *untracked = ud; memcpy(untracked->name, data, len + 1); data = next; diff --git a/fast-import.c b/fast-import.c index 6c13472c4..3e294c2b5 100644 --- a/fast-import.c +++ b/fast-import.c @@ -875,7 +875,7 @@ static struct tree_content *dup_tree_content(struct tree_content *s) for (i = 0; i < s->entry_count; i++) { a = s->entries[i]; b = new_tree_entry(); - memcpy(b, a, sizeof(*a)); + *b = *a; if (a->tree && is_null_sha1(b->versions[1].sha1)) b->tree = dup_tree_content(a->tree); else @@ -1685,7 +1685,7 @@ static int tree_content_remove( del_entry: if (backup_leaf) - memcpy(backup_leaf, e, sizeof(*backup_leaf)); + *backup_leaf = *e; else if (e->tree) release_tree_content_recursive(e->tree); e->tree = NULL; @@ -1735,7 +1735,7 @@ static int tree_content_get( return 0; found_entry: - memcpy(leaf, e, sizeof(*leaf)); + *leaf = *e; if (e->tree && is_null_sha1(e->versions[1].sha1)) leaf->tree = dup_tree_content(e->tree); else diff --git a/line-log.c b/line-log.c index 64f141e20..de5bbb5bd 100644 --- a/line-log.c +++ b/line-log.c @@ -765,7 +765,7 @@ static void move_diff_queue(struct diff_queue_struct *dst, struct diff_queue_struct *src) { assert(src != dst); - memcpy(dst, src, sizeof(struct diff_queue_struct)); + *dst = *src; DIFF_QUEUE_CLEAR(src); }