Tim (previously) supports a relatively ancient C++ application. And that creates some interesting conundrums, as the way you wrote C++ in 2003 is not the way you would write it even a few years later. The standard matured quickly.

Way back in 2003, it was still common to use C-style strings, instead of the C++ std::string type. It seems silly, but people had Strong Opinions™ about using standard library types, and much of your C++ code was probably interacting with C libraries, so yeah, C-strings stuck around for a long time.

For Tim's company, however, the migration away from C-strings was in 2007.

So they wrote this:

if( ! strncmp( pdf->symTabName().c_str(), prefix.c_str(), strlen( prefix.c_str() ) ) ) {
    // do stuff
}

This is doing a "starts with" check. strncmp, strlen are both functions which operate on C-strings. So we compare the symTabName against the prefix, but only look at as many characters as are in the prefix. As is common, strncmp returns 0 if the two strings are equal, so we negate that to say "if the symTabName starts with prefix, do stuff".

In C code, this is very much how you would do this, though you might contemplate turning it into a function. Though maybe not.

In C++, in 2007, you do not have a built-in starts_with function- you have to wait until the C++20 standard for that- but you have some string handling functions which could make this more clear. As Tim points out, the "correct" answer is: if(pdf->symTabName().find(prefix) != 0UL). It's more readable, it doesn't involve poking around with char*s, and also isn't spamming that extra whitespace between every parenthesis and operator.

Tim writes: "String handling in C++ is pretty terrible, but it doesn't have to be this terrible."

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.