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."