1

I read somewhere (cannot find the source now) that

MyClass *p1 = new MyClass;

and

MyClass *p2 = new MyClass();

are essentially equivalent, provided that MyClass provides a default constructor. The compiler understands what I want to do and adds the empty parentheses.

If this is the case, why I am not allowed to write

throw MyException;

but have to use

throw MyException();

? (Yep, a question mark at the beginning of a line.)

To add some more confusion, the C++ FAQ suggests that the second usecase (new MyClass()) does not invoke a constructor, but calls function defined with operator() instead.

peter.slizik
  • 1,839
  • 16
  • 26
  • 5
    An interesting quirk in C++: You cannot have value-initialized automatic objects, and you cannot have default-initialized temporary objects. – Kerrek SB Sep 27 '12 at 11:56

3 Answers3

3

The compiler understands what I want to do and adds the empty parentheses.

No it doesn't; the two expressions aren't quite equivalent. The difference is in how the objects are are initialised: the first uses default-initialisation, while the second uses value-initialisation. So they are equivalent for classes that define a default constructor; otherwise, the first will leave POD objects uninitialised, while the second will initialise them to zero.

why I am not allowed to write throw MyException;?

MyException() is an expression that creates a value-initialised temporary object; you can throw that just like you can throw the value of any other suitable expression.

MyException isn't an expression; it's just a type name. You can only throw the value of an expression, so throw MyException; is not valid. There's no way to create a default-initialised temporary.

To add some more confusion, the C++ FAQ suggests that the second usecase (new MyClass()) does not invoke a constructor, but calls function defined with operator() instead.

No it doesn't. It says that a declaration like List x(); declares a function with a return type List, not (as one might think) a value-initialised object of type List. It has nothing to do with new-expressions or operator().

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
  • To make sure that I understand properly: _"the first uses default-initialisation, while the second uses value-initialisation."_ This means that the first one calls the default constructor, whereas the second one creates a temporary object and uses the assignment operator? – peter.slizik Sep 27 '12 at 15:28
  • @peter.slizik: No. If the class has a non-trivial default constructor, then both will use that. If it doesn't, then default-initialisation will leave POD objects uninitialised, while value-initialisation will initialise them to zero values. Neither will create a temporary or use assignment. – Mike Seymour Sep 27 '12 at 15:32
  • @peter.slizik: See [this question](http://stackoverflow.com/questions/1613341) for more details about the various types of initialisation in C++. – Mike Seymour Sep 27 '12 at 15:36
  • Thank you for the link, I never heard of the distinction. The reason is probably here: _One thing to realize is that 'value-initialization' is new with the C++ 2003 standard - it doesn't exist in the original 1998 standard._ – peter.slizik Sep 28 '12 at 10:45
1

Because you are not throwing new exception, but rather constructing it.

Consider following:

MyException exception = MyException(); // works
MyException exception = MyException; // doesn't work

new MyException; // works
new MyException();// works
nothrow
  • 14,840
  • 6
  • 50
  • 97
0

The situation listed in the FAQ is different and doesn't apply here.

MyException is just a type name in the first case, and creates a variable in the second. That's just the syntax. Same as

MyException ex = MyException;

wouldn't compile, but

MyException ex = MyException();

would. The FAQ example illustrates simply the equivalent of:

MyException ex();

which would indeed be a function declaration, whereas:

MyException ex;

would.

There's no way that

throw MyException();

or

MyException ex = MyException();

could be interpreted as a function declaration, so they work.

Luchian Grigore
  • 236,802
  • 53
  • 428
  • 594