git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "René Scharfe" <l.s.r@web.de>
To: Jeff King <peff@peff.net>
Cc: Duy Nguyen <pclouds@gmail.com>, Git List <git@vger.kernel.org>,
	Junio C Hamano <gitster@pobox.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: Re: [PATCH 1/5] add SWAP macro
Date: Sat, 29 Apr 2017 20:16:17 +0200	[thread overview]
Message-ID: <11699799-6bdf-484d-5a1c-8e8fa7981594@web.de> (raw)
In-Reply-To: <20170428214934.tuqihgch6qeen3ni@sigill.intra.peff.net>

Am 28.04.2017 um 23:49 schrieb Jeff King:
> On Fri, Apr 28, 2017 at 07:04:51PM +0200, René Scharfe wrote:
> 
>>> What should:
>>>
>>>     SWAP(foo[i], foo[j]);
>>>
>>> do when i == j? With this code, it ends up calling
>>>
>>>     memcpy(&foo[i], &foo[j], ...);
>>>
>>> which can cause valgrind to complain about overlapping memory. I suspect
>>> in practice that noop copies are better off than partial overlaps, but I
>>> think it does still violate the standard.
>>>
>>> Is it worth comparing the pointers and bailing early?
>>
>> Hmm, so swapping a value with itself can be a useful thing to do?
>> Otherwise an assert would be more appropriate.
> 
> No, I doubt that it's useful, and it's probably a sign of a bug
> elsewhere. But it's likely a _harmless_ bug, so it may be irritating to
> die when we hit it rather than continuing.
> 
> I dunno. I could go either way. Or we could leave it as-is, and let
> valgrind find the problem. That has zero run-time cost, but of course
> nobody bothers to run valgrind outside of the test suite, so the inputs
> are not usually very exotic.

It would be  problematic on platforms where memcpy has to erase the
destination before writing new values (I don't know any example).

We could use two temporary buffers.  The object code is the same with
GCC around 5 and Clang 3.2 or higher -- at least for prio-queue.c.

With GCC 4.9.2 (that's what Debian stable currently has) the result is
actually slightly better with two buffers because a 128-bit move starts
to get used (https://godbolt.org/g/18HQDQ).

>> Swapping with *partial* overlap sounds tricky, or even evil.  If
>> we want to support that for some reason we'd have to use memmove
>> in the middle.  But that would still corrupt at least one of the
>> objects, wouldn't it?
> 
> Yes, the overlap case is probably an actual bug. Detecting it is a bit
> harder, but definitely possible. I hate to pay the run-time cost for it,
> but I wonder if a compiler could optimize it out.

How is it possible to arrive at such a situation?  We'd need two objects
of the same size (we check that in SWAP) and one of them would start
inside of the other one, i.e. the pointer difference between them would
be a fraction of 1.  So the type system would have to be tricked into
it, right?

How *would* we detect overlaps?  The obvious checks (a+len<=b||b+len<=a)
are undefined if applied to objects that don't belong to the same array.
And members of the same array would not overlap to begin with..

It may be my laziness speaking, but do we really need such a check?  If
someone constructs interleaving objects then they'd need to implement
the necessary checks themselves IMHO.

>> The line in question is this one:
>>
>> 	for (i = 0; i <= (j = (queue->nr - 1) - i); i++)
>>
>> Assignment in the middle?  Hmm.  Why not do it like this?
>>
>> 	for (i = 0, j = queue->nr - 1; i < j; i++, j--)
>>
>> Looks less complicated to me.
> 
> Yes, see my other reply. :)

Ah, so that's where I stole it from. ;)  Perhaps my source amnesia was
in part caused by confusion about your reasoning there: The code does A,
B would be better, so let's do C.  Wait, what? :)

René

  reply	other threads:[~2017-04-29 18:16 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-28 21:13 [PATCH 0/5] introduce SWAP macro René Scharfe
2017-01-28 21:38 ` [PATCH 1/5] add " René Scharfe
2017-01-30 15:39   ` Johannes Schindelin
2017-01-30 16:48     ` René Scharfe
2017-01-30 20:48       ` Johannes Schindelin
2017-01-30 21:46         ` René Scharfe
2017-01-31 12:13           ` Johannes Schindelin
2017-01-31 21:02             ` René Scharfe
2017-02-01  0:44               ` Ramsay Jones
2017-02-01 11:39               ` Johannes Schindelin
2017-01-30 16:01   ` Johannes Schindelin
2017-01-30 16:59     ` René Scharfe
2017-01-30 18:41     ` Johannes Sixt
2017-01-30 21:03       ` Johannes Schindelin
2017-01-30 22:09         ` René Scharfe
2017-01-30 22:21           ` Brandon Williams
2017-01-31 21:03             ` René Scharfe
2017-01-31 21:35               ` Jeff King
2017-01-31 22:29                 ` Junio C Hamano
2017-01-31 22:36                   ` Jeff King
2017-02-01 11:28                 ` Johannes Schindelin
2017-02-01 11:47                   ` Jeff King
2017-02-01 18:06                     ` René Scharfe
2017-02-01 18:33                       ` Junio C Hamano
2017-02-07 22:04                         ` René Scharfe
2017-02-07 22:30                           ` Junio C Hamano
2017-02-08 15:14                             ` Johannes Schindelin
2017-01-31 12:03           ` Johannes Schindelin
2017-04-24 11:29   ` Jeff King
2017-04-24 11:49     ` Jeff King
2017-04-24 13:13       ` Duy Nguyen
2017-04-28 17:04     ` René Scharfe
2017-04-28 21:49       ` Jeff King
2017-04-29 18:16         ` René Scharfe [this message]
2017-04-30  3:11           ` Jeff King
2017-05-02  5:29             ` René Scharfe
2017-01-28 21:40 ` [PATCH 2/5] apply: use " René Scharfe
2017-01-28 21:40 ` [PATCH 3/5] " René Scharfe
2017-01-30 16:03   ` Johannes Schindelin
2017-01-30 17:18     ` René Scharfe
2017-01-30 22:22   ` Junio C Hamano
2017-01-31 21:02     ` René Scharfe
2017-01-28 21:41 ` [PATCH 4/5] diff: " René Scharfe
2017-01-30 16:04   ` Johannes Schindelin
2017-01-30 17:26     ` René Scharfe
2017-01-30 22:22   ` Junio C Hamano
2017-01-28 21:42 ` [PATCH 5/5] graph: " René Scharfe
2017-01-30 16:16   ` Johannes Schindelin
2017-01-30 17:41     ` René Scharfe
2017-01-30 23:20 ` [PATCH 0/5] introduce " Junio C Hamano

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11699799-6bdf-484d-5a1c-8e8fa7981594@web.de \
    --to=l.s.r@web.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    --cc=pclouds@gmail.com \
    --cc=peff@peff.net \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).