(no subject)

Jul 06, 2011 06:25

* Did you know that, in C++, this is undefined?:

std::string toRet;
toRet.append( "stuff" );

Apparently appending to an std::string which contains 'nothing' - ie, is undefined - is undefined in itself. I did not know that! It works fine anyway under the MS compiler/stl but dies horribly under GCC/cygwin, as it leaves the std::string contents undefined. Thanks to Kat for pointing that one out! :|

* FINALLY got all my tests passing under Cygwin GCC! Fun fact: vsnprintf under Cygwin behaves oddly. It's designed to unroll a C variable-length argument list (similar to what printf and friends take) in to a string, like an sprintf for varargs. It takes an output buffer size, and if the input is longer than this buffer is documented (AFAICT!) to return the full length necessary, so you can do

char* out = (char)malloc(11);
int sizeNeeded = vsnprintf(out, 10, "Entry name %s value %d", myVarArgList);
if (sizeNeeded>10)
.. more buffer size needed ..
else
.. copied all OK.

This is in contrast to the VS CRT vsnprintf, which will return -1 if the buffer is too small (and you specify this behaviour with the _TRUNCATE flag). I merrily coded away, using an #ifdef _MSC_VER to check for -1 only under VS, only to find that, no, cygwin will return -1 on error as well. I'm not sure if Cyg is trying to follow the MS way of doing things (and/or I'm reading the documentation wrongly). Either way, it took me a good few hours to hunt down.

* It's taken me arrouunnddd three days to get the GCC build working again, and building cleanly. It used to work when I was working on b0rk last, and throw a million build warnings, but I let it break and didn't attach a high priority to fixing it. In fixing it up and clearing the backlog of build warnings I've found three or four (I think!) genuine bugs in b0rk which would've broken things later on (one was a classic C "if (a=b)" as opposed to 'if (a==b)' bug, in a particularly difficult-to-test portion of my code, which was already
breaking things subtly enough not to break them). Then there was one or three things I'd done oddly in the code which I hadn't realised - minor, non-breaking things like having a signed ID number field as opposed to unsigned, which I'd have probably made a bad assumption about in the future and introduced bugs over. I think that's three days well spent, even if it initially felt like I was wasting my time on something relatively minor. Plus, of course, I now get code coverage info via GCov again.

* Speaking of code coverage info via GCov, I thought of a feature which might be handy - the ability to mark a specific line of source code as requiring test coverage. The buildserver could then fail a build if this line isn't tested, ensuring that my tests are exercising the code they are intended to. Like this:

void functionToTest()
{
if (someComplexConditionWeThinkIsFalseAtRunTime)
return;

doSomeThing(); // MUSTTEST
.. other code ..
return;

}

Some would argue that the necessity of such a mechanism is highlighting a shortcoming in my code - ie, I haven't written it to be testable properly - and they may well be right. But I'm finding that, practically speaking, constructs similar to the above are occurring fairly frequently in my code (there's slightly more to it, in reality). The obvious answer is just to test the 'doSomeThing' method, but I want to test _all_ the logic in the functionToTest, including the lines after it.
This would have the benefit of being easy to specify the test name, too, like '// MUSTTEST:myTest'. I'm tempted to go ahead and write it - it'd be dead easy to add it in to my GCov-parsing code - but I'm not 100% sure if I'm ignoring the underlying problem (ie, my code being hard to test). Might discuss it with Kat later on. It's times like this I miss having someone older and more experienced around to advise me.

* Kat's birthday is tomorrow. I'm super excited!

cruisecontrol, b0rk, kat, c, code, testing, securityscanner

Previous post Next post
Up