Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-22 Thread Junio C Hamano
Jeff King  writes:

> Well, no, I mostly just said that I do not think there is any point in
> defining NDEBUG in the first place, as there is little or no benefit to
> removing those asserts from the built product.
> ...
> Sure, if you want to mass-convert them, doing so with a macro similar to
> assert is the simplest way. I don't think we are in a huge hurry to do
> that conversion though. I'm not complaining that NDEBUG works as
> advertised by disabling asserts. I'm just claiming that it's largely
> pointless in our code base, and I'd consider die("BUG") to be our
> "usual" style. 

I agree with all of the above. Given the way how our own code uses
assert(), there is little point removing them and turning them over
time into "if (...) die(BUG)" would probably be better.

Borrowed code like nedmalloc may be a different story, but as you
said in a separate message in this thread, I think we are better off
leaving that to those who care about that piece of code.


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-21 Thread Jeff King
On Wed, Dec 21, 2016 at 07:53:15PM -0800, Kyle J. McKay wrote:

> It seems to me what you are saying is that Git's "assert" calls are
> DIAGNOSTIC and therefore belong in a release build -- well, except for the
> nedmalloc "assert" calls which do not.

Yes, I think that is a good way of thinking about it (modulo that I
really can't say one way or the other about nedmalloc's uses).

There _are_ some DEBUG-type things in Git that are protected by #ifdefs
that default to "off" (grep for DIFF_DEBUG, for instance). I'm actually
of the opinion that debugging code like that should be in all builds and
triggerable at run-time, provided it carries no significant performance
penalty when the run-time switch is not enabled. But I do agree that's a
totally separate question than from your DEBUG/DIAGNOSTIC distinction.

-Peff


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-21 Thread Kyle J. McKay

On Dec 21, 2016, at 18:21, Kyle J. McKay wrote:


On Dec 21, 2016, at 07:55, Jeff King wrote:


On Tue, Dec 20, 2016 at 09:54:15PM -0800, Kyle J. McKay wrote:

I wasn't aware anybody actually built with NDEBUG at all. You'd  
have to

explicitly ask for it via CFLAGS, so I assume most people don't.


Not a good assumption.  You know what happens when you assume[1],  
right? ;)


Kind of. If it's a configuration that nobody[1] in the Git  
development
community intended to support or test, then isn't the person  
triggering

it the one making assumptions?


No, I don't think so.  NDEBUG is very clearly specified in POSIX [1].

If NDEBUG is defined then "assert(...)" disappears (and in a nice  
way so as not to precipitate "unused variable" warnings).  "N" being  
"No" or "Not" or "Negated" or "bar over the top" + "DEBUG" meaning  
Not DEBUG.  So the code that goes away when NDEBUG is defined is  
clearly debug code.


I think there is a useful distinction here that I make that's worth  
sharing.  Perhaps it's splitting hairs, but I categorize this "extra"  
code that we've been discussing ("assert(...)" or "if (!...) die(...)"  
or "verify(...)" into two groups:



1) DEBUG code

This is code that developers use when creating new features.  Or  
helpful code that's needed when stepping through a program with the  
debugger to debug a problem.  Or even code that's only used by some  
kind of external "test".  It may be expensive, it may do things that  
should never be done in a build for wider consumption (such as write  
information to special log files, write special syslog messages  
etc.).  Often this code is used in combination with a "-g" debug  
symbols build and possibly even a "-O0" or "-O1" option.


Code like this has no place in a release executable meant for general  
use by an end user.


2) DIAGNOSTIC code

This is near zero overhead code that is intended to be left in a  
release build meant for general use and normally sits there not doing  
anything and NOT leaching any performance out of the build either.   
Its sole purpose in life is to provide a trail of "bread crumbs" if  
the executable goes ***BOOM***.  These "bread crumbs" should be just  
enough when combined with feedback from the unfortunate user who  
experienced the meltdown to re-create the issue in a real DEBUG build  
and find and fix the problem.



It seems to me what you are saying is that Git's "assert" calls are  
DIAGNOSTIC and therefore belong in a release build -- well, except for  
the nedmalloc "assert" calls which do not.


What I'm saying is if they are diagnostic and not debug (and I'm not  
arguing one way or the other, but you've already indicated they are  
near zero overhead which suggests they are indeed diagnostic in  
nature), then they do not belong inside an "assert" which can be  
disabled with "NDEBUG".  I'm arguing that "assert" is not intended for  
diagnostic code, but only debug code as used by nedmalloc.  Having Git  
treat "NDEBUG" one way -- "no, no, do NOT define NDEBUG because that  
disables Git diagnostics and I promise you there's no performance  
penalty" -- versus nedmalloc -- "yes, yes please DO define NDEBUG  
unless you really need our slow debugging code to be present for  
debugging purposes" -- just creates needless unnecessary confusion.


--Kyle


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-21 Thread Jeff King
On Wed, Dec 21, 2016 at 06:21:37PM -0800, Kyle J. McKay wrote:

> > Kind of. If it's a configuration that nobody[1] in the Git development
> > community intended to support or test, then isn't the person triggering
> > it the one making assumptions?
> 
> No, I don't think so.  NDEBUG is very clearly specified in POSIX [1].

I know what NDEBUG is, and I know it is widely used in other projects.
My claim is only that I do not think that the use of NDEBUG was
generally considered when people wrote assert() in git. That is
certainly true of me. I don't know about other developers.

> > I think here you are getting into superstition. Is there any single
> > assert() in Git that will actually have an impact on performance?
> 
> You have suggested there is and that Git is enabling NDEBUG for exactly that
> reason -- to increase performance:

Sorry if I wasn't clear, but I meant in Git itself, not in the nedmalloc
compat code. I think it's worth considering them separately because the
latter is not part of most Git builds in the first place, and certainly
it is written in a different style, and may have different assumptions
about how people might build it.

I do not know the nedmalloc code well at all. I gave a brief read of the
results of "git grep 'assert('" and it looked like some of its
assertions are more involved than simple comparisons. So I guessed that
perhaps the reason that NDEBUG was added there when the code was
imported is that there is a performance difference there. But that's
just a guess. It may or may not be borne out by measurements.

I'd be surprised if any of the assertions in the rest of git have a
noticeable impact (and I could not detect one by running t/perf).

> > What would be the advantage of that over `if(...) die("BUG: ...")`? It
> > does not require you to write a reason in the die(), but I am not sure
> > that is a good thing.
> 
> You have stated that you believe the current "assert" calls in Git
> (excluding nedmalloc) should not magically disappear when NDEBUG is defined.

Well, no, I mostly just said that I do not think there is any point in
defining NDEBUG in the first place, as there is little or no benefit to
removing those asserts from the built product.

> So precluding a more labor intensive approach where all currently existing
> "assert(...)" calls are replaced with an "if (!...) die(...)" combination,
> providing a "verify" macro is a quick way to make that happen.  Consider
> this, was the value that Jonathan provided for the "die" string immediately
> obvious to you?  It sure wasn't to me.  That means that whoever does the
> "assert(...)" -> "if(!...)die" swap out may need to be intimately familiar
> with that particular piece of code or the result will be no better than
> using a "verify" macro.

Sure, if you want to mass-convert them, doing so with a macro similar to
assert is the simplest way. I don't think we are in a huge hurry to do
that conversion though. I'm not complaining that NDEBUG works as
advertised by disabling asserts. I'm just claiming that it's largely
pointless in our code base, and I'd consider die("BUG") to be our
"usual" style. If any change is to be made, it would be to suggest
people prefer die("BUG") as a style guideline for future patches. But I
haven't seen anybody agree (or disagree) with the notion, so I'd
hesitate to impose my style suggestion without more discussion in that
area.

If we _did_ accept that as a style guideline, then we could move over
existing assert() calls over time (either as janitorial projects, or as
people touch the related code). But there's not a pressing need to do it
quickly.

-Peff


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-21 Thread Kyle J. McKay

On Dec 21, 2016, at 07:55, Jeff King wrote:


On Tue, Dec 20, 2016 at 09:54:15PM -0800, Kyle J. McKay wrote:

I wasn't aware anybody actually built with NDEBUG at all. You'd  
have to

explicitly ask for it via CFLAGS, so I assume most people don't.


Not a good assumption.  You know what happens when you assume[1],  
right? ;)


Kind of. If it's a configuration that nobody[1] in the Git development
community intended to support or test, then isn't the person  
triggering

it the one making assumptions?


No, I don't think so.  NDEBUG is very clearly specified in POSIX [1].

If NDEBUG is defined then "assert(...)" disappears (and in a nice way  
so as not to precipitate "unused variable" warnings).  "N" being "No"  
or "Not" or "Negated" or "bar over the top" + "DEBUG" meaning Not  
DEBUG.  So the code that goes away when NDEBUG is defined is clearly  
debug code.


Considering the wide deployment and use of Git at this point I think  
rather the opposite to be true that "Git does Not require DEBUGging  
code to be enabled for everyday use."  The alternative that it does  
suggests it's not ready for prime time and quite clearly that's not  
the case.


I've been defining NDEBUG whenever I make a release build for quite  
some
time (not just for Git) in order to squeeze every last possible  
drop of

performance out of it.


I think here you are getting into superstition. Is there any single
assert() in Git that will actually have an impact on performance?


You have suggested there is and that Git is enabling NDEBUG for  
exactly that reason -- to increase performance:



On Dec 20, 2016, at 08:45, Jeff King wrote:

I do notice that we set NDEBUG for nedmalloc, though if I am  
reading the

Makefile right, it is just for compiling those files. It looks like
there are a ton of asserts there that _are_ potentially expensive



Perhaps Git should provide a "verify" macro.  Works like "assert"  
except
that it doesn't go away when NDEBUG is defined.  Being Git-provided  
it could
also use Git's die function.  Then Git could do a global replace of  
assert

with verify and institute a no-assert policy.


What would be the advantage of that over `if(...) die("BUG: ...")`? It
does not require you to write a reason in the die(), but I am not sure
that is a good thing.


You have stated that you believe the current "assert" calls in Git  
(excluding nedmalloc) should not magically disappear when NDEBUG is  
defined.  So precluding a more labor intensive approach where all  
currently existing "assert(...)" calls are replaced with an "if (!...)  
die(...)" combination, providing a "verify" macro is a quick way to  
make that happen.  Consider this, was the value that Jonathan provided  
for the "die" string immediately obvious to you?  It sure wasn't to  
me.  That means that whoever does the "assert(...)" -> "if(!...)die"  
swap out may need to be intimately familiar with that particular piece  
of code or the result will be no better than using a "verify" macro.


I'm just trying to find a quick and easy way to accommodate your  
wishes without redefining the semantics of NDEBUG. ;)


--Kyle

[1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/assert.h.html


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-21 Thread Jeff King
On Tue, Dec 20, 2016 at 09:54:15PM -0800, Kyle J. McKay wrote:

> > I wasn't aware anybody actually built with NDEBUG at all. You'd have to
> > explicitly ask for it via CFLAGS, so I assume most people don't.
> 
> Not a good assumption.  You know what happens when you assume[1], right? ;)

Kind of. If it's a configuration that nobody[1] in the Git development
community intended to support or test, then isn't the person triggering
it the one making assumptions?

At any rate, I agree that setting NDEBUG should not create a broken
program, and some solution like your patch is a good idea here. I was
mainly speaking to the "do not bother" comment. It is not that I do not
bother to build with NDEBUG, it is that I think it is actively a bad
idea.

[1] Maybe I am alone in my surprise, and everybody working on Git is
using assert() with the intention that it can be disabled. But if
that were the case, I'd expect more push-back against "die(BUG)"
which does not have this feature. I don't recall a single discussion
to that effect, and searching for NDEBUG in the list archives turns
up hardly any mentions.

> I've been defining NDEBUG whenever I make a release build for quite some
> time (not just for Git) in order to squeeze every last possible drop of
> performance out of it.

I think here you are getting into superstition. Is there any single
assert() in Git that will actually have an impact on performance?

I'd be more impressed if you could show some operation that is faster
when built with NDEBUG than without. Running all of t/perf does not seem
to show any difference, and looking at the asserts themselves, they're
almost all single-instruction compares in code that isn't performance
critical anyway.

> > So from my perspective it is not so much "do not bother with release
> > builds" as "are release builds even a thing for git?"
> 
> They should be if you're deploying Git in a performance critical
> environment.

I hope my history of patches shows that I do care about deploying Git in
a performance critical environment. But I only care about performance
tradeoffs that have a _measurable_ gain.

> Perhaps Git should provide a "verify" macro.  Works like "assert" except
> that it doesn't go away when NDEBUG is defined.  Being Git-provided it could
> also use Git's die function.  Then Git could do a global replace of assert
> with verify and institute a no-assert policy.

What would be the advantage of that over `if(...) die("BUG: ...")`? It
does not require you to write a reason in the die(), but I am not sure
that is a good thing.

> > I do notice that we set NDEBUG for nedmalloc, though if I am reading the
> > Makefile right, it is just for compiling those files. It looks like
> > there are a ton of asserts there that _are_ potentially expensive, so
> > that makes sense.
> 
> So there's no way to get a non-release build of nedmalloc inside Git then
> without hacking the Makefile?  What if you need those assertions enabled?
> Maybe NDEBUG shouldn't be defined by default for any files.

AFAICT, yes. I'd leave it to people who actually build with nedmalloc to
decide whether it is worth caring about, and whether the asserts there
have a noticeable performance impact.

-Peff


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-20 Thread Kyle J. McKay

On Dec 20, 2016, at 08:45, Jeff King wrote:


On Tue, Dec 20, 2016 at 03:12:35PM +0100, Johannes Schindelin wrote:


On Dec 19, 2016, at 09:45, Johannes Schindelin wrote:

ACK. I noticed this problem (and fixed it independently as a part  
of a
huge patch series I did not get around to submit yet) while  
trying to

get Git to build correctly with Visual C.


Does this mean that Dscho and I are the only ones who add -DNDEBUG  
for
release builds?  Or are we just the only ones who actually run the  
test

suite on such builds?


It seems you and I are for the moment the only ones bothering with  
running

the test suite on release builds.


I wasn't aware anybody actually built with NDEBUG at all. You'd have  
to

explicitly ask for it via CFLAGS, so I assume most people don't.


Not a good assumption.  You know what happens when you assume[1],  
right? ;)


I've been defining NDEBUG whenever I make a release build for quite  
some time (not just for Git) in order to squeeze every last possible  
drop of performance out of it.


Certainly I never have when deploying to GitHub's cluster (let alone  
my

personal use), and I note that the Debian package also does not.


Yeah, I don't do it for my personal use because those are often not  
based on a release tag so I want to see any assertion failures that  
might happen and they're also not performance critical either.



So from my perspective it is not so much "do not bother with release
builds" as "are release builds even a thing for git?"


They should be if you're deploying Git in a performance critical  
environment.



One of the
reasons I suggested switching the assert() to a die("BUG") is that the
latter cannot be disabled. We generally seem to prefer those to  
assert()

in our code-base (though there is certainly a mix). If the assertions
are not expensive to compute, I think it is better to keep them in for
all builds. I'd much rather get a report from a user that says "I hit
this BUG" than "git segfaulted and I have no idea where" (of course I
prefer a backtrace even more, but that's not always an option).


Perhaps Git should provide a "verify" macro.  Works like "assert"  
except that it doesn't go away when NDEBUG is defined.  Being Git- 
provided it could also use Git's die function.  Then Git could do a  
global replace of assert with verify and institute a no-assert policy.


I do notice that we set NDEBUG for nedmalloc, though if I am reading  
the

Makefile right, it is just for compiling those files. It looks like
there are a ton of asserts there that _are_ potentially expensive, so
that makes sense.


So there's no way to get a non-release build of nedmalloc inside Git  
then without hacking the Makefile?  What if you need those assertions  
enabled?  Maybe NDEBUG shouldn't be defined by default for any files.


--Kyle

[1] https://www.youtube.com/watch?v=KEP1acj29-Y


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-20 Thread Jeff King
On Tue, Dec 20, 2016 at 03:12:35PM +0100, Johannes Schindelin wrote:

> > On Dec 19, 2016, at 09:45, Johannes Schindelin wrote:
> > 
> > >ACK. I noticed this problem (and fixed it independently as a part of a
> > >huge patch series I did not get around to submit yet) while trying to
> > >get Git to build correctly with Visual C.
> > 
> > Does this mean that Dscho and I are the only ones who add -DNDEBUG for
> > release builds?  Or are we just the only ones who actually run the test
> > suite on such builds?
> 
> It seems you and I are for the moment the only ones bothering with running
> the test suite on release builds.

I wasn't aware anybody actually built with NDEBUG at all. You'd have to
explicitly ask for it via CFLAGS, so I assume most people don't.
Certainly I never have when deploying to GitHub's cluster (let alone my
personal use), and I note that the Debian package also does not.

So from my perspective it is not so much "do not bother with release
builds" as "are release builds even a thing for git?".  One of the
reasons I suggested switching the assert() to a die("BUG") is that the
latter cannot be disabled. We generally seem to prefer those to assert()
in our code-base (though there is certainly a mix). If the assertions
are not expensive to compute, I think it is better to keep them in for
all builds. I'd much rather get a report from a user that says "I hit
this BUG" than "git segfaulted and I have no idea where" (of course I
prefer a backtrace even more, but that's not always an option).

I do notice that we set NDEBUG for nedmalloc, though if I am reading the
Makefile right, it is just for compiling those files. It looks like
there are a ton of asserts there that _are_ potentially expensive, so
that makes sense.

-Peff


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-20 Thread Johannes Schindelin
Hi Kyle,

On Mon, 19 Dec 2016, Kyle J. McKay wrote:

> On Dec 19, 2016, at 09:45, Johannes Schindelin wrote:
> 
> >ACK. I noticed this problem (and fixed it independently as a part of a
> >huge patch series I did not get around to submit yet) while trying to
> >get Git to build correctly with Visual C.
> 
> Does this mean that Dscho and I are the only ones who add -DNDEBUG for
> release builds?  Or are we just the only ones who actually run the test
> suite on such builds?

It seems you and I are for the moment the only ones bothering with running
the test suite on release builds.

Ciao,
Johannes


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-19 Thread Junio C Hamano
Jonathan Tan  writes:

>>> This is obviously an improvement, but it makes me wonder if we should be
>>> doing:
>>>
>>>  if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data))
>>> die("BUG: some explanation of why this can never happen");
>>>
>>> which perhaps documents the intended assumptions more clearly. A comment
>>> regarding the side effects might also be helpful.
>>
>> I wondered exactly the same thing myself.  I was hoping Jonathan would
>> pipe in here with some analysis about whether this is:
>>
>>   a) a super paranoid, just-in-case, can't really ever fail because by
>> the time we get to this code we've already effectively validated
>> everything that could cause check_header to return false in this case
>> ...
> The answer is "a". The only time that mi->inbody_header_accum is
> appended to is in check_inbody_header, and appending onto a blank
> mi->inbody_header_accum always happens when is_inbody_header is true
> (which guarantees a prefix that causes check_header to always return
> true).
>
> Peff's suggestion sounds reasonable to me, maybe with an error message
> like "BUG: inbody_header_accum, if not empty, must always contain a
> valid in-body header".

OK.  So we do not expect it to fail, but we still do want the side
effect of that function (i.e. accmulation into the field).

Somebody care to send a final "agreed-upon" version?


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-19 Thread Jonathan Tan

On 12/19/2016 12:38 PM, Kyle J. McKay wrote:

On Dec 19, 2016, at 12:03, Jeff King wrote:


On Sat, Dec 17, 2016 at 11:54:18AM -0800, Kyle J. McKay wrote:


Since 6b4b013f18 (mailinfo: handle in-body header continuations,
2016-09-20, v2.11.0) mailinfo.c has contained new code with an
assert of the form:

assert(call_a_function(...))


Thanks for spotting this - I'm not sure how I missed that.


This is obviously an improvement, but it makes me wonder if we should be
doing:

 if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data))
die("BUG: some explanation of why this can never happen");

which perhaps documents the intended assumptions more clearly. A comment
regarding the side effects might also be helpful.


I wondered exactly the same thing myself.  I was hoping Jonathan would
pipe in here with some analysis about whether this is:

  a) a super paranoid, just-in-case, can't really ever fail because by
the time we get to this code we've already effectively validated
everything that could cause check_header to return false in this case

-or-

  b) Yeah, it could fail in the real world and it should "die" (and
probably have a test added that triggers such death)

-or-

  c) Actually, if check_header does return false we can keep going
without problem

-or-

  d) Actually, if check_header does return false we can keep going by
making a minor change that should be in the patch

I assume that since Jonathan added the code he will just know the answer
as to which one it is and I won't have to rely on the results of my
imaginary analysis.  ;)


The answer is "a". The only time that mi->inbody_header_accum is 
appended to is in check_inbody_header, and appending onto a blank 
mi->inbody_header_accum always happens when is_inbody_header is true 
(which guarantees a prefix that causes check_header to always return true).


Peff's suggestion sounds reasonable to me, maybe with an error message 
like "BUG: inbody_header_accum, if not empty, must always contain a 
valid in-body header".


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-19 Thread Kyle J. McKay

On Dec 19, 2016, at 12:03, Jeff King wrote:


On Sat, Dec 17, 2016 at 11:54:18AM -0800, Kyle J. McKay wrote:


Since 6b4b013f18 (mailinfo: handle in-body header continuations,
2016-09-20, v2.11.0) mailinfo.c has contained new code with an
assert of the form:

assert(call_a_function(...))

The function in question, check_header, has side effects.  This
means that when NDEBUG is defined during a release build the
function call is omitted entirely, the side effects do not
take place and tests (fortunately) start failing.

Move the function call outside of the assert and assert on
the result of the function call instead so that the code
still works properly in a release build and passes the tests.

Signed-off-by: Kyle J. McKay 
---

Notes:
   Please include this PATCH in 2.11.x maint


This is obviously an improvement, but it makes me wonder if we  
should be

doing:

 if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data))
die("BUG: some explanation of why this can never happen");

which perhaps documents the intended assumptions more clearly. A  
comment

regarding the side effects might also be helpful.


I wondered exactly the same thing myself.  I was hoping Jonathan would  
pipe in here with some analysis about whether this is:


  a) a super paranoid, just-in-case, can't really ever fail because  
by the time we get to this code we've already effectively validated  
everything that could cause check_header to return false in this case


-or-

  b) Yeah, it could fail in the real world and it should "die" (and  
probably have a test added that triggers such death)


-or-

  c) Actually, if check_header does return false we can keep going  
without problem


-or-

  d) Actually, if check_header does return false we can keep going by  
making a minor change that should be in the patch


I assume that since Jonathan added the code he will just know the  
answer as to which one it is and I won't have to rely on the results  
of my imaginary analysis.  ;)


On Dec 19, 2016, at 09:45, Johannes Schindelin wrote:


ACK. I noticed this problem (and fixed it independently as a part of a
huge patch series I did not get around to submit yet) while trying  
to get

Git to build correctly with Visual C.


Does this mean that Dscho and I are the only ones who add -DNDEBUG for  
release builds?  Or are we just the only ones who actually run the  
test suite on such builds?


--Kyle


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-19 Thread Jeff King
On Sat, Dec 17, 2016 at 11:54:18AM -0800, Kyle J. McKay wrote:

> Since 6b4b013f18 (mailinfo: handle in-body header continuations,
> 2016-09-20, v2.11.0) mailinfo.c has contained new code with an
> assert of the form:
> 
>   assert(call_a_function(...))
> 
> The function in question, check_header, has side effects.  This
> means that when NDEBUG is defined during a release build the
> function call is omitted entirely, the side effects do not
> take place and tests (fortunately) start failing.
> 
> Move the function call outside of the assert and assert on
> the result of the function call instead so that the code
> still works properly in a release build and passes the tests.
> 
> Signed-off-by: Kyle J. McKay 
> ---
> 
> Notes:
> Please include this PATCH in 2.11.x maint

This is obviously an improvement, but it makes me wonder if we should be
doing:

  if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data))
die("BUG: some explanation of why this can never happen");

which perhaps documents the intended assumptions more clearly. A comment
regarding the side effects might also be helpful.

-Peff


Re: [PATCH] mailinfo.c: move side-effects outside of assert

2016-12-19 Thread Johannes Schindelin
Hi,

On Sat, 17 Dec 2016, Kyle J. McKay wrote:

> Since 6b4b013f18 (mailinfo: handle in-body header continuations,
> 2016-09-20, v2.11.0) mailinfo.c has contained new code with an
> assert of the form:
> 
>   assert(call_a_function(...))
> 
> The function in question, check_header, has side effects.  This
> means that when NDEBUG is defined during a release build the
> function call is omitted entirely, the side effects do not
> take place and tests (fortunately) start failing.
> 
> Move the function call outside of the assert and assert on
> the result of the function call instead so that the code
> still works properly in a release build and passes the tests.
> 
> Signed-off-by: Kyle J. McKay 

ACK. I noticed this problem (and fixed it independently as a part of a
huge patch series I did not get around to submit yet) while trying to get
Git to build correctly with Visual C.

Ciao,
Dscho


[PATCH] mailinfo.c: move side-effects outside of assert

2016-12-17 Thread Kyle J. McKay
Since 6b4b013f18 (mailinfo: handle in-body header continuations,
2016-09-20, v2.11.0) mailinfo.c has contained new code with an
assert of the form:

assert(call_a_function(...))

The function in question, check_header, has side effects.  This
means that when NDEBUG is defined during a release build the
function call is omitted entirely, the side effects do not
take place and tests (fortunately) start failing.

Move the function call outside of the assert and assert on
the result of the function call instead so that the code
still works properly in a release build and passes the tests.

Signed-off-by: Kyle J. McKay 
---

Notes:
Please include this PATCH in 2.11.x maint

 mailinfo.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mailinfo.c b/mailinfo.c
index 2fb3877e..47442fb5 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -708,9 +708,12 @@ static int is_scissors_line(const char *line)
 
 static void flush_inbody_header_accum(struct mailinfo *mi)
 {
+   int okay;
+
if (!mi->inbody_header_accum.len)
return;
-   assert(check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data, 0));
+   okay = check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data, 0);
+   assert(okay);
strbuf_reset(&mi->inbody_header_accum);
 }
 
---