Modern C++

Initialize Member Variables in the Order You Declare Them

In part 4 of this series on the C++ Core Guidelines, Kate Gregory reminds you of an oddity in C++ when it comes to initializing member variables, and shows you a best practice that will make sure this oddity never hurts you.

I looked at constructors last time and why you'd want to initialize member variables instead of using default constructors. This time out, I want to show you a strange language wrinkle that's been around since day one, and demonstrate the good habit that will keep the wrinkle from hurting you.

I'm going to vary from my format for a moment, and not quote the guideline right away. Instead, I'm going to pose you a puzzle: What is the value of w.x after the code in Listing 1 runs?

Listing 1: Class with initialization in the constructor
class Wrinkle
{
public:
  Wrinkle(int i) : a(++i), b(++i), x(++i) {}
private:
  int a;
  int x;
  int b;
};


int main()
{
  Wrinkle w(0);
  return 0;
}

Most people assume a will be 1, b will be 2 and x will be 3. But, in fact, a is 1, x is 2 and b is 3. (Go ahead, test it yourself with a debugger.) Why? Because the initializer expressions happen in the order the variables are declared in the class -- not the order the initializer expressions appear in the constructor.

If you didn't know that, don't feel bad -- lots of good C++ developers don't know that. And they shouldn't have to know that, either -- you should write your code in a way that doesn't deceive people. That means, just as C.47 says: Define and initialize member variables in the order of member declaration.

If I rearrange the member variable declarations, I can change the values that end up in those member variables when the initializer runs. Now, this is a fake example -- why would anyone increment a parameter as they walked through the initialization process? Even so, you'll often see one variable initialized from another, for example FullName being initialized from FirstName and LastName, or a pointer variable being initialized with a call to new, and another variable initialized with a call to some function of that newly created object. When helpful tools or eager new employees rearrange the declarations in the class -- putting variables in alphabetical order, or grouping like with like -- suddenly the code stops working. Actually, you're lucky if it's sudden -- that probably means you have a great suite of unit tests. More likely it won't cause a problem for weeks, and by that time nobody remembers the minor tidying up so they have no idea what's gone wrong.

The best approach, of course, would be to have initializers that don't depend on each other, so you don't care what order they happen in. But if you can't do that, you need to defend against the day someone rearranges things. If you always write your initializers in the same order as the variables are declared, and rearrange your initializers when you rearrange your variables, you're far less likely to be surprised. If nothing else, dropping a comment into the class warning future people not to rearrange your declaration order might also help prevent trouble, if one variable truly depends on another and initialization order matters.

I chose this guideline because it's an example of protecting people from an oddity of the language. Reading all the guidelines and doing your best to follow them all will increase what you know about C++, even as it's reducing the need for you to know all of those details.

This little wrinkle only matters in my life about once a decade, but when it bites it bites hard, partly because I can stare for hours, believing I know what order things are happening in, and not knowing I'm wrong. Following this guideline can help you to ensure this particular language wrinkle never bites you.

About the Author

Kate Gregory has been using C++ since before Microsoft had a C++ compiler, and has been paid to program since 1979. Kate runs a small consulting firm in rural Ontario, Canada, and provides mentoring and management consultant services, as well as writing code every week. She has spoken all over the world, written over a dozen books, and helped thousands of developers to be better at what they do. Kate is a Microsoft Regional Director, a Visual C++ MVP, an Imagine Cup judge and mentor, and an active contributor to StackOverflow and StackExchange sites. She develops courses for Pluralsight, primarily on C++ and Visual Studio. Since its founding in 2014 she is the Open Content Chair and speaker for CppCon, the definitive C++ conference.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events