tags:

views:

111

answers:

1

How do compilers know how to correctly handle this code?

struct Foo
{
    int bar;

    Foo()
    {
        bar = 3;
    }

    Foo& operator=(const Foo& other)
    {
        bar = other.bar;
        return *this;
    }

    int SetBar(int newBar)
    {
        return bar = newBar;
    }
};

static Foo baz;
static Foo someOtherBaz = baz;
static int placeholder = baz.SetBar(4);

What would the final value of someOtherBaz.bar be?

+10  A: 

The value of someOtherBaz.bar would be 3.

Static objects within a translation unit are constructed in the order they appear within the TU (note, there is no defined order of static object in different translation units).

  1. First, baz will be constructed with the default constructor. This will set baz.bar to 3.
  2. Next someOtherBaz will be constructed via the copy constructor. Since no copy constructor was defined, a default copy constructor will be used which will just copy each field. So someOtherBaz.bar will be given the value of 3.
  3. Finally, to construct placeholder, baz.SetBar will be called which will also change the value of baz (but not someOtherBaz since they are independent objects; while you created someOtherBaz based on the value of baz, they are different objects so can change independently).

So, at the end, you'll have:

 baz.bar: 4
 someOtherBaz.bar: 3
 placeholder: 4
R Samuel Klatchko
@Samuel: I've a doubt. After the construction of `someOtherBaz`, using the compiler-provided copy constructor, will the assignment operator function be called for `static Foo someOtherBaz = baz;`? Else what's the meaning of the assignment here?
legends2k
@legends2k - for single argument constructors, `TYPE t = arg` is the same as `TYPE t(arg)`.
R Samuel Klatchko
@legend22K - there is no assignment in the code - the use of the = symbol is not an assignment, it is a copy constructor invocation.
anon
@Neil: Oh thanks, makes it clear! If it invokes the copy constructor and not the assignment operation, in case if it's a no argument constructor, what if there's only one constructor which takes say two arguments. Did Samuel mean single argument constructors or no argument constructors?
legends2k
@legends2K No matter what, T t = ... will NEVER use the assignment operator. It is an initialisation, not an assignment.
anon
What if all the variables were in separate translation units, referring to each other via externs?
Clark Gaebel
I guess that'll lead to a "static initialization fiasco" (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.13); perhaps Neil or Samuel can enlighten us here.
legends2k
@wowus - there is no defined order between initialization of global objects in different translation units. So if you had `extern Foo f1; Foo f2 = f1;` you may initialize f2 from the raw uninitialized memory of f1.
R Samuel Klatchko
Okay, thanks...
Clark Gaebel