Reputation: 5084
void foo()
{
//some code
MyClass m();
//some more code
}
Does the C++ standard ensure that the constructor of class MyClass
will be called after //some code
has run, or is it unspecified behavior?
Upvotes: 4
Views: 134
Reputation: 299920
Supposing that you meant to declare a variable, as has been remarked already:
void foo() {
// {before}
MyClass m;
// {after}
}
Then semantically, the constructor is executed after {before} and before {after}.
Whether this holds during execution is covered by the as-if rule. That is, in order to allow optimizations, the Standard only offer guarantees about observable effects: whatever the execution model chosen, the observable effects should be as-if the code had been executed without any optimization.
Observable effects notably include:
volatile
variablesBy default, a function whose definition is unknown is supposed to have observable effects.
The notable exception is the Copy Elision optimization, which the Standard allows in a number of cases even though the copy constructor might have observable effects.
Concretely, it means that given:
int before();
int after();
void foo() {
int n = 5;
int const a = before();
n += a;
MyClass m;
int const c = after();
n += c;
std::cout << n << "\n";
}
The Standard guarantees the following ordering:
before();
MyClass m;
after();
std::cout << n << "\n";
What is not guaranteed, however, is how n
is computed. All that is known is that at the moment of printing it, it will be equal to 5 + a + c
, but whether the computation is delayed to just before printing or performed eagerly each time a new element is available is of no concern to you: it does not change the observable behavior.
Therefore, the two following versions of foo
are equivalent:
void foo_eager() {
int n = 5;
n += before();
MyClass m;
n += after();
std::cout << n << "\n";
}
void foo_lazy() {
int const a = before();
MyClass m;
int const c = after();
std::cout << (5 + a + c) << "\n";
}
Upvotes: 0
Reputation: 1153
MyClass m();
--> No object is being created here. Its just a declaration of function which takes no parameters but returns MyClass object.
If you need to create an object just write MyClass m;
or MyClass *m = new MyClass();
Yes, constructor of MyClass is called after some code.
Upvotes: 0
Reputation: 372814
The technical answer to this question is that the compiler will guarantee that the constructor isn't run at all, because the line
MyClass m();
is not a variable declaration. Instead, it's a prototype for a function called m
that takes no arguments and returns a MyClass
. To make this into an object, you need to drop the parens:
MyClass m;
Because this is such a source of confusion, in C++11 there is a new syntax you can use for initializing automatic objects. Instead of using parentheses, use curly braces, like this:
MyClass m{};
This tells the compiler to use the nullary constructor for MyClass
as intended, since there's no way to interpret the above as a function prototype.
If you make this change, the compiler will guarantee that m
's constructor is executed after the first piece of code and before the second piece of code.
Hope this helps!
Upvotes: 4
Reputation: 73443
First of all MyClass m();
doesn't create any object, you probably meant MyClass m;
. Yes, it is guaranteed that the object is created only after //some code
is ran.
Upvotes: 3
Reputation: 206546
There is no object being created here.
MyClass m();
Declares a function by the name m
which takes no arguments and returns a object of type MyClass
.
MyClass m
would create a object named m
of the type MyClass
and yes it is guaranteed that constructor for m
will be called only when the that line of code is executed.
Upvotes: 1