C++ Compiler allows circular definition?
Since "root" on the RHS is a flat-out undeclared variable.
It's not undeclared. It is declared by that very same statement. However, root
is uninitialised at the point where AddLeaf(root)
is called, so when the value of the object is used (compared to null etc.) within the function, the behaviour is undefined.
Yes, using a variable in its own declaration is allowed, but using its value is not. Pretty much all you can do with it is take the address or create a reference, or expressions that only deal with type of the sub expression such as sizeof
and alignof
.
Yes, there are use cases although they may be rare. For example, you might want to represent a graph, and you might have a constructor for node that takes a pointer to linked node as an argument and you might want to be able to represent a node that links with itself. Thus you might write Node n(&n)
. I won't argue whether that would be a good design for a graph API.
That's an unfortunate side-effect of definitions in C++, that declaration and definition is done as separate steps. Because the variables are declared first, they can be used in their own initialization:
std::shared_ptr<Node> root = tree.AddLeaf(12, root);
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
Declaration of the variable Initialization clause of variable
Once the variable is declared, it can be used in the initialization for the full definition of itself.
It will lead to undefined behavior in AddLeaf
if the data of the second argument is used, as the variable is not initialized.