So I almost got burned by a function. Partly my fault, because I didn’t read the online documentation on it. I looked at the API in the header file, and it had very limited documentation, but mostly enough for me to figure out it. I also happened to be looking at the implementation, and noticed that I was hanging onto a live wire. So the API looks like this, with the names changed to keep this general:
char *RenderSomeStringConversion(const char *in, char *out, size_t *out_size);
Now, the out_size parameter should have warned me a little, since it’s a pointer to the size. Maybe I should have looked further there. Anyway, the API takes the input string, does translation on it, and dumps the result in the output buffer, and returns the output buffer. C programmers are used to functions like this returning the output buffer, so that’s not a really good warning about what this thing can do to you. OK, so the landmine this API sets out for you is that the function will attempt the transformation, and if it decides that it can’t fit the result in your output buffer, it will call realloc on your pointer. IOW, there’s no way to use this method without involving yourself with malloc/free. And worse, most of the time, if you’ve got a static buffer that’s a good size, this API will work just fine, but instead of failing when it isn’t big enough, it will just burn you if you run into the edge case. And it will be so much more fun to debug if you were to, say, pass in the address of a local that’s too small, because then it will call realloc on a pointer into your stack, and off you’ll go someday, launched into some interesting area of memory to execute god knows what bits.
Now, in the online docs, this is actually well documented, but this is an API that’s part of a permanent API broadly available to people, and it’s just got this awful nasty sticky thing on it. A little more time could have produced an API that didn’t have this dependency or trap.Posted by Eli Boling on March 15th, 2012 under C_Builder |