Inconsistency Isn’t Harmless


Few characteristics lead to interfaces that are easy to use correctly as much as consistency, and few characteristics lead to aggravating interfaces as much as inconsistency. . . . Some developers think that integrated development environments (IDEs) render such inconsistencies unimportant, but they are mistaken. Inconsistency imposes mental friction into a developer’s work that no IDE can fully remove.

Effective C++ (Third Edition) by Scott Meyers
Item 18, Page 80, Paragraph 5

My official position on code style is consistency.

int Good()
{
    int x=5;
    return x;
}
int AlsoGood() {
    int x=5;
    return x;
}
int Foo() {
    int x=5;
    return x;
}

int Bar()
{
    int x=5;
    return x;
}

I don’t care if you prefer C-style or Java-style braces. I don’t care if you prefer tabs or spaces. I don’t care if you prefer spaces around your operators or not. I do care that you pick one and maintain that choice throughout all of your code!

My go-to example of what not to do was the .NET platform until yesterday. If you want the size of something in .NET, it might be .Size(), or .Count, or .Length. You never know, and the rationale for the choice isn’t always apparent. Yes, Intellisense is great and will help you find the correct one quickly, but that doesn’t change the fact that I shouldn’t have to find it.

Yesterday, I had the unfortunate “pleasure” of stumbling across a better example. In the Qt framework, every class’s members are accessed via an accessor function. So unlike .NET’s properties, a Qt object’s size would be accessed through .size(), not .Size, unless you’re using QJsonParseError, that is. No, the way to access the error code is .error, not .error(). And to make matters worse, the compiler error you get if you use .error() doesn’t make this immediately apparent.

currentstateparser.cpp:69:18: error: called object type 'QJsonParseError::ParseError' is not a function or function pointer
                if (error.error() != QJsonParseError::NoError)
                    ~~~~~~~~~~~^

What on earth does this mean? What is ::ParseError? I never wrote that. Typical compiler spam (see my post: “Errors From Another Planet“). This is the only place I know of in the Qt framework where, for some reason unknown to me, you have to access the public member directly, rather than through an accessor. It doesn’t help that everyone’s example code uses .error(), which if they took a moment test their code before they posted misleading information, they would find it doesn’t even compile.

Don’t do this in your code! If you wrap member variables in accessor functions, then wrap them all. If you don’t, then don’t, for them all. Help those who want to use your interface correctly use it correctly.


Leave a Reply