--- Dan Scott <[EMAIL PROTECTED]> wrote: <snip -- about nul-filling buffers>
I think the best rationale for pre-filling buffers is that, if you're going to have problems with a buffer -- such as a wild pointer pointing into the unused portion -- you want the code to fail in a consistent and reproducible way. Miker hinted at this notion at one point, in a posting from July 13, referring to "the principle of least surprise." While I can appreciate the principle, I think there are better ways to apply it. First, I wouldn't initialize the buffer with nuls. I'd initialize it with (for example) exclamation points, with perhaps a nul at the end. That way if a wayward pointer gives us a string of exclamation points, we'll have a better chance of recognizing the problem. A string of nuls is neither distinctive nor informative. Secondly, I would confine the buffer-filling to test builds, so that we don't incur the overhead in production builds. For example (uncompiled and untested): #ifdef NDEBUG #define osrf_prefill( s, n ) #else #define osrf_prefill( s, n ) \ do { \ void * temp_s = (s); \ size_t temp_n = (n); \ memset( temp_s, '!', temp_n ); \ temp_s[ temp_n - 1 ] = '\0'; \ } while( 0 ) #endif (I use temp_s and temp_n to avoid evaluating the arguments more than once.) This approach may require some non-trivial rearrangement of the Makefiles so that we could readily use or not use the debugging versions of things. I am not the one to judge whether it would be worth the trouble. Of course none of the above applies to the use of memset in safe_malloc. In that case the client code relies on the initialization with zeros. I am tempted to create a safe_calloc, identical to the present safe_malloc except in name. Then anywhere we really need the zeros we can switch to safe_calloc. In the fullness of time we could remove the memset from safe_malloc. (Of course for consistency we should probably have a safe_strdup and maybe a safe_realloc. As it stands now, we lock the front door but leave the back door wide open.) <snip> > Actually, if I'm reading it correctly, C99 does guarantee the > null-terminating behaviour: <snip -- quotes from the Standard> > (Spec is at > http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf) I stand corrected. I had relied on various man files, all of which were more than a little vague on this point. I have the C89 Standard within reach but I didn't have the C99 Standard. Now I do. Thanks for contributing to my education. Nevertheless, it might be prudent to add a nul manually at the end of the receiving buffer after calling snprintf, in the rare cases where you want to use the truncated string. Despite what the Standard says, not all snprintfs are created equal. In particular some of them treat the return code differently, and may vary in other ways for all I know. Scott McKellar http://home.swbell.net/mck9/ct/