10 ms·
I don't feel like the crc32 example is a good one. Maybe the game entities example would have been better...
by swah 11y ago
I don't feel like the crc32 example is a good one. Maybe the game entities example would have been better...
- deathanatos 11y agoIIRC, MD5 (and probably the other hashs) are implemented in exactly this form in OpenSSL. I can't really think of a more straightforward way to implement CRC32, frankly, especially assuming that maybe you don't want to force the entire buffer to be present. If you did, you could `uint32_t crc32(unsigned char * buffer, size_t len);` — but you can implement that function in terms of the interface in the article, and if you pick up a bit of inlining from an optimizer, I think it would end up being just as efficient, too. (If you don't, you'll end up with some extra pointer dereferences, but again, the streaming interface supports streaming.) And perhaps to stress what some other commenters are missing: it's not "you should always OO in C"; it's that if you want an interface to compute, while streaming, the CRC32 of a stream — you need to store that state somewhere, and you need to act on that state somehow. That state is an object: it has a setup, and potentially a teardown, and two relevant methods: feed it data, and get the computed hash.
- exDM69 11y agoCRCs or MD5 or other hash sums don't require inheritance or other OO tricks or even constructors or destructors (apart from zero-initialization). The state is just a single integer. For other hashes, the state might be slightly more complicated but there's still no need for fancy OO. If you want to build a system where you can change the hash function at runtime, you might need some kind of interface or inheritance. But if you end up needing a virtual call per byte (or per a small chunk of bytes), you're killing your performance. And besides, there's so few hash functions you end up needing in practice that a simple switch-case would do the same with less boilerplate and probably give better performance because compiler optimizations can take place (virtual calls tend to prevent many optimization tricks). I agree with GP... The choice of CRC was a poor example for an article about OO in C. Something related to filesystems or device drivers would be vastly more practical.
- swah 11y agoThat's what I meant - the state is a uint32_t that you pass to the crc32_calc_next_byte function...
- deathanatos 11y ago> CRCs or MD5 or other hash sums don't require inheritance or other OO tricks Given some of the other comments, I think this ought to be stressed though… OO doesn't strictly require inheritance, or vtables. A fair number of classes in the C++ STL don't use those features, for example. It's not that the state is a single integer, either, it's that the concept of a state exists; having a separate type (with the functions surrounding that separate type) exist to embody that concept, and can change a function from an ambiguous "what goes in this uint32_t arg?" to a very obvious md5_state_t. > or even constructors or destructors (apart from zero-initialization). Just a nit: MD5 requires initialization that is more than just zero-initialization. > probably give better performance because compiler optimizations can take place (virtual calls tend to prevent many optimization tricks). This is about the most concrete argument against vtables (but hardly against OO in general) thus far, and I'd still love more explanation: what makes a branch more optimizable than following a pointer?