6
#include <iostream>

struct Box
{
    Box()            { std::cout << "constructor called" << std::endl; }
    Box(const Box&)  { std::cout << "Copy constructor called" << std::endl; }
    Box(Box&&)       { std::cout << "Move constructor called" << std::endl; }
    void run() const { std::cout << "Run" << std::endl;}
};

int main()
{
    Box a(Box());
    a.run();
}

(demo)

In the above code I was expecting either Copy Constuctor or Move Constructor to be called on passing anonymous object Box() as argument. But none of them were called. Reason probably might be copy elision. But even constructor is not called for anonymous object A(). Actually, the above code does not compile and on calling run() function compiler gave following error.

a.cpp: In function ‘int main()’:
a.cpp:28:7: error: request for member ‘run’ in ‘a’, which is of non-class type ‘Box(Box (*)())’
     a.run();

So when we type Box a(Box()) what is happening? What is being created?

Vivek
  • 448
  • 2
  • 11
  • 3
    You've been bitten by MVP. It thinks `Box a(Box());` is a declaration of a function named `a` returning a `Box`. – Borgleader Aug 18 '17 at 13:36
  • @YSC I'm not sure if I agree with your formatting -- I preferred the previous version. – pingul Aug 18 '17 at 13:46
  • 1
    @pingul shorter codes tend to attract more attention on SO, and my edit does not (I hope) alter the original intent of OP. But its definitely their call to rollback it. – YSC Aug 18 '17 at 13:49
  • 4
    Possible duplicate of [Most vexing parse: why doesn't A a(()); work?](https://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work) – underscore_d Aug 20 '17 at 10:31

1 Answers1

15

This is a case of the Most Vexing Parse. When something could be parsed as a function declaration, it is.

Box a(Box())

is the declaration of a function named a taking a function of type Box (*)() as argument and returning a Box.

A solution is to use the (new in C++11) aggregate initialization for constructing your objects:

Box a{Box{}}

(demo)


The MVP is discussed in its simplest form in this stackoverflow question Most vexing parse: why doesn't A a(()); work?

If you do have an expression within then it is valid. For example:

((0));//compiles

To learn more about how languages are defined, and how compilers work, you should learn about Formal language theory or more specifically Context Free Grammars (CFG) and related material like finite state machines. If you are interested in that though the wikipedia pages won't be enough, you'll have to get a book.

Community
  • 1
  • 1
YSC
  • 38,212
  • 9
  • 96
  • 149