• Create Account

### #ActualCornstalks

Posted 03 December 2012 - 09:54 PM

Ok when i saw that code i thought hmm pretty clear it should be the int constructor since the object doesn'exist yet....then i saw your explanation and i shrug...really? then i tried it just to be sure....first instinct was right your "spoiler" is wrong

Did you miss the comment about copy elision? The compiler is allowed to optimize away the temporary, even if there are side effects. It doesn't have to, but it may (and most probably will). Some compilers may, and some may not. Some may with certain optimization settings, some may not. But it's important to remember that you may be constructing two MyStructs (the temporary, and the one you want) because, depending on what MyStruct is and what its constructor/destructor does, there may be side effects. It's another one of these "Betcha didn't see that coming, now did ya?!" that C++ can throw at you, because you test it a thousand times on a compiler/platform, and it works a specific way, and then you test the same code on another compiler/platform and it does something a little different.

If you don't believe me that both the int constructor and copy constructor are used in that code, try this:
class MyClass
{
private:
MyClass(const MyClass&) {} // It shouldn't need this, right?

public:
MyClass() {}
MyClass(int i) {}
MyClass& operator = (int) { return *this; }
};

MyClass s = 5;

As expected, compilation fails. So now we see that the copy constructor is indeed needed and used. But what happens if we run this code:
#include <iostream>

class MyClass
{
public:
MyClass() { std::cout << "MyClass()" << std::endl; }
MyClass(int) { std::cout << "MyClass(int)" << std::endl; }
MyClass(const MyClass&) { std::cout << "MyClass(const MyClass&)" << std::endl; }
MyClass& operator = (int) {  std::cout << "MyClass& operator = (int)" << std::endl; return *this; }
};

int main()
{
MyClass s = 5;
}


It's a big WTF if you ask me. The copy constructor is required for it to compile (because it's technically required to do MyClass s(MyClass(5))), but it's never even called in the final code! Classic example of copy elision.

@Grafalgar: My posts show one example of exactly what you're looking for. Beginners are taught early on about constructors, but this little detail can potentially be a big pain in the butt that they don't learn until years later.

### #1Cornstalks

Posted 03 December 2012 - 09:49 PM

Ok when i saw that code i thought hmm pretty clear it should be the int constructor since the object doesn'exist yet....then i saw your explanation and i shrug...really? then i tried it just to be sure....first instinct was right your "spoiler" is wrong

Did you miss the comment about copy elision? The compiler is allowed to optimize away the temporary, even if there are side effects. It doesn't have to, but it may (and most probably will). Some compilers may, and some may not. Some may with certain optimization settings, some may not. But it's important to remember that you may be constructing two MyStructs (the temporary, and the one you want) because, depending on what MyStruct is and what its constructor/destructor does, there may be side effects. It's another one of these "Betcha didn't see that coming, now did ya?!" that C++ can throw at you, because you test it a thousand times on a compiler/platform, and it works a specific way, and then you test the same code on another compiler/platform and it does something a little different.

If you don't believe me that both the int constructor and copy constructor are used in that code, try this:
class MyClass
{
private:
MyClass(const MyClass&) {} // It shouldn't need this, right?

public:
MyClass() {}
MyClass(int i) {}
MyClass& operator = (int) { return *this; }
};

MyClass s = 5;

As expected, compilation fails.

@Grafalgar: My posts show one example of exactly what you're looking for. Beginners are taught early on about constructors, but this little detail can potentially be a big pain in the butt that they don't learn until years later.

PARTNERS