LWN: Comments on "Zeuthen: Writing a C library, part 1" https://lwn.net/Articles/449452/ This is a special feed containing comments posted to the individual LWN article titled "Zeuthen: Writing a C library, part 1". en-us Fri, 19 Sep 2025 09:54:40 +0000 Fri, 19 Sep 2025 09:54:40 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450787/ https://lwn.net/Articles/450787/ kabloom <div class="FormattedComment"> Yes. ulimit is one way to get allocation errors even with overcommit enabled.<br> </div> Fri, 08 Jul 2011 01:41:19 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450786/ https://lwn.net/Articles/450786/ kabloom <div class="FormattedComment"> Does Windows overcommit? Windows programs don't fork the way Linux programs do, so I would guess that overcommitting memory is much less of a problem on Windows.<br> </div> Fri, 08 Jul 2011 01:40:05 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450541/ https://lwn.net/Articles/450541/ jwakely <i>&gt; In general, you can't return both results *and* error codes.</i> <pre> std::future&lt;double&gt; squerrt(double x) { std::promise&lt;double&gt; p; if (x &lt; 0) p.set_exception(copy_exception(std::domain_error("negative"))); else p.set_value(sqrt(x)); return p.get_future(); } int main() { double i = squerrt(-1).get(); // boom } </pre> Thu, 07 Jul 2011 12:08:36 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450493/ https://lwn.net/Articles/450493/ cmccabe <div class="FormattedComment"> <font class="QuotedText">&gt; In general, you can't return both results *and* error codes. (As I said, </font><br> <font class="QuotedText">&gt; for pointers you can return NULL, and for functions whose domain of valid </font><br> <font class="QuotedText">&gt; results is limited in some sense [abs()], you can, but if you're returning </font><br> <font class="QuotedText">&gt; anything other than a pointer, int-type or floating-point-type, you're </font><br> <font class="QuotedText">&gt; basically hosed.</font><br> <font class="QuotedText">&gt; </font><br> <p> If we're still talking about C/C++, then you can only ever return:<br> * a primitive (int, float, etc.)<br> * a pointer<br> * a struct<br> <p> All of those have a natural 'none of the above' value. Integer types have 0 or a negative, floats and doubles have NaN, and pointers have NULL.<br> <p> If you're returning a struct by value, then you're probably using C++, since C programmers rarely return an entire structure by value. The obvious thing to do is to either return an integer error code and take a reference to the thing to be modified, or use C++ exceptions. Either way, problem solved.<br> <p> Being able to return multiple values at once is nice, but it's hardly the biggest challenge when using C or C++.<br> </div> Thu, 07 Jul 2011 00:22:36 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450374/ https://lwn.net/Articles/450374/ vlovich <div class="FormattedComment"> Same here. I mean it's been a while since I took data structures. Maybe things have changed ;).<br> </div> Wed, 06 Jul 2011 16:56:11 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450366/ https://lwn.net/Articles/450366/ jwakely <div class="FormattedComment"> <a href="http://www.cprogramming.com/tutorial/lesson18.html">http://www.cprogramming.com/tutorial/lesson18.html</a><br> </div> Wed, 06 Jul 2011 16:01:44 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450363/ https://lwn.net/Articles/450363/ jwakely <div class="FormattedComment"> I'm glad someone sensible agrees with the point I made way back in <a href="http://lwn.net/Articles/449645/">http://lwn.net/Articles/449645/</a> ... I was starting to think I was going mad and everyone else knew something about RB trees that I didn't<br> <p> </div> Wed, 06 Jul 2011 15:56:53 +0000 Zeuthen: Writing a C library, part 2 https://lwn.net/Articles/450360/ https://lwn.net/Articles/450360/ jwakely <div class="FormattedComment"> <font class="QuotedText">&gt; In other words, this is a gcc-specific ELF extension.</font><br> <p> It's not gcc-specific, it's done by GNU binutils not gcc<br> <p> <a href="http://sourceware.org/binutils/docs-2.21/as/Symver.html">http://sourceware.org/binutils/docs-2.21/as/Symver.html</a><br> <a href="http://sourceware.org/binutils/docs-2.21/ld/VERSION.html">http://sourceware.org/binutils/docs-2.21/ld/VERSION.html</a><br> <p> </div> Wed, 06 Jul 2011 15:54:16 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450137/ https://lwn.net/Articles/450137/ dgm <div class="FormattedComment"> I'm afraid your simple example got much more flak that it deserved. People, it was only an example! The truth is, if I had a dime for every time I have seen something like what you pointed out, I would be rich by now. <br> <p> The problem with encapsulation (and information hiding in general) is that sometimes you _need_ to take the implementation into account. It doesn't mean that it's not a great engineering principle, it is. It's just that it sometimes makes things complicated. In this case, before you can use something in a destructor you have to be pretty sure that the implementation will not throw an exception. That's not only difficult to do, it's subject to constant change in current development paradigms.<br> <p> <font class="QuotedText">&gt; I get annoyed when people talk about exceptions as a panacea for error handling problems.</font><br> <p> Me too. No amount of exceptions, garbage collectors or type inference can replace your brain. They are there you help you with the grunt work, but it doesn't mean you can forget how to properly engineer stuff, because from time to time, you need to.<br> <p> <font class="QuotedText">&gt; It's simple enough to avoid new and free, but once you start needing to implement transactional behavior-- either a function call succeeds or it fails, but it doesn't leave a mess-- things get difficult.</font><br> <p> So true. I have come to the conclusion that error handling is maybe 30-50% of the effort needed to get properly done code. And regretfully is often a neglected part. For instance, what you call transactional behavior is called "class invariants" in OO programming. It's critical to well behaved long living programs, but many people haven't head about them (for those: no action should let an object in an inconsistent state).<br> </div> Mon, 04 Jul 2011 00:11:56 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450136/ https://lwn.net/Articles/450136/ nix <div class="FormattedComment"> And then we can write a nice high-performance FUSE filesystem on top of the relational database! And then we can run MySQL on top of that! (And then we can run the FUSE filesystem atop that, and run a virtual machine inside that filesystem. And then we have a nice room heater.)<br> <p> </div> Sun, 03 Jul 2011 23:40:31 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450135/ https://lwn.net/Articles/450135/ dgm <div class="FormattedComment"> We can probably shortcircuit the flamewar by using a relational database. Oh, noes! PostgreSQL vs. MySQL anyone? ;-)<br> </div> Sun, 03 Jul 2011 23:09:00 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450132/ https://lwn.net/Articles/450132/ nix <div class="FormattedComment"> I think we are in violent agreement.<br> <p> </div> Sun, 03 Jul 2011 22:04:53 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450129/ https://lwn.net/Articles/450129/ dark What you gain is a destructor that works in O(n) time and does no allocations. By reusing the child pointers as a linked list, you avoid having to make any allocations for it.<p> I think your approach can get there too, with some refinement. How are you implementing the inorder visit? Sun, 03 Jul 2011 20:48:54 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450124/ https://lwn.net/Articles/450124/ vlovich <div class="FormattedComment"> Rebalancing the tree would be enormously redundant - the extra 4-6 lines of really simple code is worth it (hell, if you're lazy, provide a boolean to the internal delete function that says whether or not to rebalance). <br> <p> Thread-safety is irrelevant here - if you can access the tree after the destructor is already called, you've failed at thread safety (actually you've failed at maintaining the lifetime of the object properly).<br> </div> Sun, 03 Jul 2011 19:39:19 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450121/ https://lwn.net/Articles/450121/ nix <div class="FormattedComment"> When you're writing a tree deallocator, I'd expect it to have privileged access to the interior of the tree. There's no reason not to use a specialized high-speed node deletor in that case: rebalancing the tree between every deletion is silly, because it will never be accessed again. (Even a multithread-safe tree should probably block and warn on accesses once tree deallocation begins: any such accesses are racy and could easily access rubbish if they happened just an instant later.)<br> </div> Sun, 03 Jul 2011 18:35:37 +0000 Zeuthen: Writing a C library, part 2 https://lwn.net/Articles/450117/ https://lwn.net/Articles/450117/ paulj <div class="FormattedComment"> Symbol map files are supported by several proprietary Unix toolchains, including Suns' and (iirc) HPs'. The syntax is nearly identical twixt Solaris and GNU (there's certainly a useful common subset iirc). The ELF symbol stuff is at least very very similar in concept. It might even be standardised, and/or tools may know the differing formats. Binary compatibility across different OSes tends not to be the most important of issues though..<br> </div> Sun, 03 Jul 2011 17:07:17 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450105/ https://lwn.net/Articles/450105/ cladisch <div class="FormattedComment"> If a generic deletion function is used, it might rebalance the tree after each step.<br> </div> Sun, 03 Jul 2011 11:35:22 +0000 Zeuthen: Writing a C library, part 2 https://lwn.net/Articles/450101/ https://lwn.net/Articles/450101/ nix <div class="FormattedComment"> Yes, its a Linuxism (and very much more useful than Solaris symbol versions), but a lot of the syntax of the file, and the underlying idea, was a Solarisism first.<br> <p> </div> Sun, 03 Jul 2011 09:39:48 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450098/ https://lwn.net/Articles/450098/ vlovich I'm not understanding the claims that it takes anything other than O(n) in the worst case for a tree de-allocation. <pre> function destroy_tree(tree) { foreach child in tree delete_tree(child) free(tree) } </pre> Sun, 03 Jul 2011 08:14:37 +0000 Zeuthen: Writing a C library, part 2 https://lwn.net/Articles/450095/ https://lwn.net/Articles/450095/ cmccabe <div class="FormattedComment"> <font class="QuotedText">&gt; And you will want to use the linker symbol versioning instead of static </font><br> <font class="QuotedText">&gt; versioning, otherwise, you'd break the API all the time. BTW, it is not a </font><br> <font class="QuotedText">&gt; gcc thing, it is an ELF thing, and Solaris has been doing it since forever.</font><br> <p> from <a href="http://www.airs.com/blog/archives/220">http://www.airs.com/blog/archives/220</a><br> <p> <font class="QuotedText">&gt; Ulrich Drepper and Eric Youngdale introduced a much more sophisticated </font><br> <font class="QuotedText">&gt; symbol versioning scheme, which is used by the glibc, the GNU linker, and </font><br> <font class="QuotedText">&gt; gold. The key differences are that versions may be specified in object </font><br> <font class="QuotedText">&gt; files and that shared libraries may contain multiple independent versions </font><br> <font class="QuotedText">&gt; of the same symbol</font><br> <p> In other words, this is a gcc-specific ELF extension. I wonder if LLVM supports it yet? I found a page from 2008 that said that LLVM didn't have support for this yet, but then I got tired of using the Google.<br> </div> Sun, 03 Jul 2011 06:30:49 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/450044/ https://lwn.net/Articles/450044/ cmccabe <div class="FormattedComment"> I never said that you "couldn't do anything useful in a destructor". Destructors are helpful in general for error handling in C++. I just said that std::bad_alloc is not a great way to handle the failure of small memory allocations.<br> <p> It is true that printf would get you out of a jam in this case, because it doesn't throw the silly bad_alloc exception when it fails to allocate memory. You could also catch bad_alloc in your destructors whenever it pops up, and try to do something reasonable. In some cases, you can force the nothrow variant of new to be used (although not when std::vector and friends are involved.) But that is going to be very difficult in any non-trivial program.<br> <p> I get annoyed when people talk about exceptions as a panacea for error handling problems. You don't have to think, just use exceptions, and your problems will magically melt away. The reality is, writing low-level code that correctly handles errors is very difficult in either C or C++. It's simple enough to avoid new and free, but once you start needing to implement transactional behavior-- either a function call succeeds or it fails, but it doesn't leave a mess-- things get difficult.<br> <p> If you find yourself in a scenario where you have to undo changes that you made earlier to some data structure, your error handling may itself encounter an error. And how do you automatically handle that? Well, you have to engage your brain and structure the operation into a prepare operation followed by a commit operation. And that is not going to be trivial in either C or C++.<br> </div> Sat, 02 Jul 2011 00:20:06 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449983/ https://lwn.net/Articles/449983/ nix <div class="FormattedComment"> Yes, probably. And then we can get into fsync() flamewars instead! Isn't POSIX fun?<br> </div> Fri, 01 Jul 2011 13:40:39 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449969/ https://lwn.net/Articles/449969/ jwakely <div class="FormattedComment"> Exactly! (on both points)<br> </div> Fri, 01 Jul 2011 10:50:46 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449957/ https://lwn.net/Articles/449957/ dgm <div class="FormattedComment"> I believe that what really paranoid programs have to do is keep critical state in non-volatile memory (a disk, a remote machine, etc), and do everything possible to ensure that it's always consistent. That way it doesn't matter if the program goes away because of a programming error, a kill signal or the power going down in the middle of a system call.<br> </div> Fri, 01 Jul 2011 09:46:33 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449958/ https://lwn.net/Articles/449958/ nix <div class="FormattedComment"> OK, so my memory was faulty :) not much of a surprise there, some days it seems it consists mostly of faults.<br> <p> </div> Fri, 01 Jul 2011 09:37:15 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449944/ https://lwn.net/Articles/449944/ whot <div class="FormattedComment"> FTR, we discouraged dbus support mostly because the communication API was less than ideal and just talking directly to hal (now udev) was more sensible.<br> <p> The abort() was extremely annoying while programming but it also lead to the code being very stable. Every small error got punished badly so we had to make sure we fixed up the code properly.<br> </div> Fri, 01 Jul 2011 05:28:29 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449939/ https://lwn.net/Articles/449939/ jwakely <div class="FormattedComment"> but it won't throw a std::bad_alloc, or any other exception, and you were talking about the dangers of exceptions being thrown from destructors, right? and how you can't do anything useful in a destructor because it might throw, and therefore "look pretty grim for RAII"<br> <p> (although I'm not sure why you were talking about that, the comment you replied to wasn't talking about exceptions *in* destructors, just exceptions *and* destructors as being helpful for error handling)<br> </div> Thu, 30 Jun 2011 23:44:24 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449920/ https://lwn.net/Articles/449920/ nix <div class="FormattedComment"> If it's a base that you can build language bindings on top of, then the libdbus-1 authors have even *less* idea than they might have as to what the process is doing, and it's even more critical that it should never die. (But it is true that a lot of Great Big Languages have no hope of handling OOM errors: dynamic allocation is too fundamental to them. However, for others this same property is a benefit, because they often have a lot of dynamically-allocated storage that they can get rid of, and even their own allocators so they can be sure the storage finds its way back to the OS again.)<br> <p> Damn good articles btw.<br> </div> Thu, 30 Jun 2011 21:12:01 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449907/ https://lwn.net/Articles/449907/ cmccabe <div class="FormattedComment"> <font class="QuotedText">&gt; So make sure your logging API supports printf-style API as</font><br> <font class="QuotedText">&gt; well (or instead of) only supporting writing a single string,</font><br> <font class="QuotedText">&gt; then you don't need to concatenate std::strings.</font><br> <p> printf can also allocate memory. That is why it is not signal-safe.<br> </div> Thu, 30 Jun 2011 19:07:37 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449886/ https://lwn.net/Articles/449886/ njs <div class="FormattedComment"> If your rebalancing algorithm doesn't require any heap allocations then right, there is no point.<br> </div> Thu, 30 Jun 2011 18:01:47 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449884/ https://lwn.net/Articles/449884/ davidz2525 <div class="FormattedComment"> I think I even prefaced the word 'people' with 'smart' :-). But, yeah, I completely agree that we're both right which is why the guidance is to establish a policy on what to do when the programmer screws up rather than doing either A or B. I brought this up mostly to address the popular misconception that libdbus-1 is an evil library that eats babies - it's not.<br> <p> (Btw, another misconception is that libdbus-1 is meant for applications to use; it's really not, it's more intended for a base that you can build language/toolkit bindings on top + the implementation used to implement dbus-daemon(1) which MUST be able to handle OOM.)<br> </div> Thu, 30 Jun 2011 17:49:05 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449860/ https://lwn.net/Articles/449860/ nix <div class="FormattedComment"> I'm not sure you *can* completely disable overcommit. Robust Unix programs theoretically have to assume that they might get killed at any instant, either due to OOM in something like the stack (which obviously cannot be trapped), or due to a user sending it a kill signal.<br> <p> Alas the latter is rare (and misbehaviour might be expected if you kill something maintaining persistent state while it is updating that state), and the former is so rare and so hard to cater to that simply nobody ever bothers. Sufficiently Paranoid Programs could avoid the stack-OOM by doing a massive deep recursion early on, to balloon their stack out to the maximum they might need. A few programs do this. You can avoid being user-killed by being installed setuid or setgid, but this has other disadvantages and is basically never done (at least not solely for this reason).<br> <p> This is probably a fault of some kind in POSIX, but I have not even the faintest glimmerings of a clue as to how to fix it.<br> <p> </div> Thu, 30 Jun 2011 15:23:30 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449859/ https://lwn.net/Articles/449859/ nix <div class="FormattedComment"> And I see David has linked to this comment with the link text 'people sometimes fail to realize that the caller has a responsibility'. I might respond that people sometimes fail to realize that libraries have a responsibility not to shoot the whole process in the head when the caller could perfectly well recover.<br> <p> (Ironically, elsewhere in the same post David comments that libraries should not manipulate signal dispositions because these are process-wide state. I'd call the continued existence of a process process-wide state, as well, but apparently David disagrees. I think his attitude leads to appalling and unnecessary instability: he thinks mine leads to unfixed bugs in callers. We are probably both right, but ne'er the twain shall meet.)<br> </div> Thu, 30 Jun 2011 15:19:30 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449831/ https://lwn.net/Articles/449831/ stevem <div class="FormattedComment"> Absolutely. 100%.<br> <p> A library should *never* call abort in an attempt at error-handling. You throw away any chance for the calling code to do sensible stuff such as clean up properly.<br> </div> Thu, 30 Jun 2011 14:08:18 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449817/ https://lwn.net/Articles/449817/ nix <blockquote> I am not sure if (with overcommit disabled) you have to allocate memory space for the entire binary or not. </blockquote> You don't. Overcommit does not apply to read-only file-backed regions, because they can be dropped at any time without harm. Thu, 30 Jun 2011 12:55:36 +0000 Are you sure? https://lwn.net/Articles/449816/ https://lwn.net/Articles/449816/ nix <div class="FormattedComment"> Yes exactly. Generally, library functions which immediately allocate storage will be returning a pointer to that storage: they can return NULL. Library functions which *call* such functions may have more complex work to do, including possibly unwinding partially-completed work. If *this* would require memory allocation, you may need to find a different algorithm, or arrange to do all allocations first (I've done both at various times).<br> <p> But saying "I won't bother, I'll just abort" is a disservice to your users, no matter *how* hard it is to handle OOM.<br> <p> </div> Thu, 30 Jun 2011 12:53:51 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449792/ https://lwn.net/Articles/449792/ MisterIO <div class="FormattedComment"> <font class="QuotedText">&gt;That deletes everything, needs no heap storage, and it's O(n (log n)^2), not so bad.</font><br> There's no point to this, a simple remove(value_at_root)(value at root simply because it's the simplest to find) for a balanced binary tree already takes O(log(n)), so why would I create a different algorithm to achieve the same performance?<br> </div> Thu, 30 Jun 2011 10:33:20 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449789/ https://lwn.net/Articles/449789/ MisterIO <div class="FormattedComment"> <font class="QuotedText">&gt;then you can put the current node on a linked list that's threaded through the left pointers</font><br> We were discussing about the problems caused by allocations in the destructor. And what exacly would I gain by doing this instead of, like I said in the first post, find_minimum(), then next() till the end and save pointers to elements on a vector, then free them all through the vector of pointers? Also, if my assumption in my second post is correct, you don't even need to save temporaries if you do an inorder visit, you just need to free the node once you've reached the parent, checking that the children have all its own children NULL(which means that you've already visited all the grandchildren).<br> </div> Thu, 30 Jun 2011 10:28:53 +0000 Zeuthen: Writing a C library, part 1 https://lwn.net/Articles/449765/ https://lwn.net/Articles/449765/ mjthayer <div class="FormattedComment"> <font class="QuotedText">&gt; large process A forks (creating A`), almost all it's memory is COW</font><br> &gt;<br> <font class="QuotedText">&gt; process B allocates some memory, but doesn't touch it yet</font><br> &gt;<br> <font class="QuotedText">&gt; process A` changes some memory (breaking COW), requiring real memory to hold the result.</font><br> &gt;<br> <font class="QuotedText">&gt;process B then tries to use the memory it had previously allocated and finds that it is not available.</font><br> That I do not see as a problem - when process B allocates the memory it is really allocated, and if A tries to use its COW memory later it will just not be there.<br> <p> <font class="QuotedText">&gt; if you could somehow define 'forked recently' in a way that could be cheap enough, then you could possibly do it.</font><br> <p> That I do see as more of a problem. One could have some background thread gradually actually allocating the process's memory, but that is replacing one piece of complexity by another.<br> <p> <font class="QuotedText">&gt; but the idea that (in the general case), this will make your system more predictable is not something I believe. you have no way of knowing _which_ process (including system daemons) will need to allocate more memory at the instant that you are out, so you really don't know which process will die anyway. (and no, in general processes and libraries don't do anything except die when they run out of memory).</font><br> <p> True, it doesn't change the fundamental problem that you need enough memory for whatever you want to do.<br> <p> <font class="QuotedText">&gt; in some ways, it would make it easier to DOS a system, just have your memory hog _not_ die if a malloc fails, instead sleep and try again. eventually something else in the system will need memory and die</font><br> <p> I thought that ulimits were supposed to solve that. Do they work as intended these days?<br> <p> <font class="QuotedText">&gt; there's also the problem that without overcommit you need to have significantly more swap enabled in the system (since you have to have enough ram+swap to handle the peak theoretical memory use from large processes doing a fork+exec)</font><br> <p> The idea was to disable overcommit except for forking, so that shouldn't be such an issue. Thinking about it one could also freeze the overcommitted process if it tries to actually use its memory and it isn't there (making sure there is a bit of memory left over for doing emergency process surgery).<br> </div> Thu, 30 Jun 2011 07:19:44 +0000 Are you sure? https://lwn.net/Articles/449761/ https://lwn.net/Articles/449761/ cpeterso <blockquote> > Your approach (the second one) would have worked, if I could have revamped the entire source base to use it. But it is rare that one gets the opportunity to do that, and malloc() tests at least don't look strange.</blockquote> <p> If you're brave, there's always the C preprocessor: <p> <pre> #define malloc(size) my_xmalloc_with_msg(size, __FILE__, __LINE__, __FUNCTION__) </pre> <p> This approach could still be useful if your macro was only #included by a subset of .c files, leaving some object code still calling libc's <code>malloc()</code>. Thu, 30 Jun 2011 06:19:11 +0000