Frederick said:
Skarmander posted:
I'm not talking about programmers, I'm talking about computers running
programs.
So am I.
If it takes 20 nanoseconds for a particular machine to check if a
pointer is null, then the execution time of your algorithm is extended by
20 nanoseconds for each time you call "free" (if every one of these null
checks is redundan). Those 20 nanoseconds could have been reclaimed if
"free" didn't check for null pointers.
And free() is going to take up much more than 20 nanoseconds, most likely an
order of magnitude more.
Whether a particular human being (aka programmer, in this context)
considers 20 nanoseconds to be negligible is irrelevant to my query.
Then your use of "inefficient" is peculiar, since efficiency never
exclusively depends on absolute execution time. If that were the case, you
should focus on making your programs much more efficient by not using
dynamic memory allocation at all, obviating any concerns about free().
More efficient. Runs faster. Uses less resources.
Your idea of better programs is limited.
Depends who you ask. I congratulate C for its efficiency. If you want your
hand to be held, you could get a wrapper library:
size_t strlen_HOLD_MY_HAND(char const *const p)
{
if (p) return strlen(p);
return 0;
}
This has nothing to do with hand-holding. If you're writing a program where
you need either the length of a string or 0 if there is no string, this
function is exactly what you want. If you're writing a program where you
need the length of a string, calling strlen() with a null pointer is an
error, since that's not a string.
For free() it was decided that calling it with a null pointer is not an
error, that "no memory" is a valid argument, and that freeing "no memory" is
a no-op. This makes sense, since malloc() may return "no memory". Again, I
maintain that the cost one pays for having these semantics, rather than more
intricate ones that allow for a slightly simpler implementation, is
insignificant.
If you want the feature of being able to invoke "free" upon a null pointer,
then all it takes is something simple like:
#define FREE_SAFE(p) do { void *const q = p; if(q) free(q); } while (0);
This way, you can use "free" whenever a null check would be redundant,
saving 20 nanoseconds in execution time.
That does not address my point, which is that nobody ever benefits enough
from those 20 nanoseconds to warrant changing the semantics of free().
Programmers who are actually concerned with omitting redundant null checks
should invest in their compiler, which is far more likely to pay off.
A check for NULL in strlen() could be significant. My bold assertion is that
a check for NULL in free() never is.
S.