Zeuthen: Writing a C library, part 1
Posted Jun 28, 2011 18:24 UTC (Tue) by
cmccabe (guest, #60281)
In reply to:
Zeuthen: Writing a C library, part 1 by gowen
Parent article:
Zeuthen: Writing a C library, part 1
> But I can't think of a sane use case where I would need to, so it's
> not really a big deal
class MyFile {
MyFile(const char *filename) { fd = open(filename); ... etc ... }
~MyFile() {
if (close(fd)) {
std::ostringstream oss;
oss << "close failed, but I can't throw an exception from "
"a destructor!";
log(oss.str().c_str());
}
}
}
However, streams can allocate memory. So if we run out of memory, get a std::bad_alloc, and try to unwind our stack, we'll probably suffer the insta-kill that happens when you throw an exception while unwinding another exception.
This is only the most simple, obvious example of why you might need to allocate memory in a constructor. Any time you put together strings with concatenation, create a stringstream object, or even call syslog, you are allocating memory. And those are all obvious things to do when handling an error.
So if you can't throw an exception, and you can't log the error, things look pretty grim for RAII. So in practice, everyone just gives up on the whole handling std::bad_alloc thing.
N.B.: In this situation, having a close method with saner error handling, in addition to the destructor, is a good idea. In that case, the caller would be expected to call close before the object is destroyed, and the destructor would just be a fallback. This is a common pattern in real-world code.
(
Log in to post comments)