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