It's legal syntax. X is in scope for its own definition. A situation where you might want an object to refer to itself is circular linked lists, along the lines of:
struct Node {
Node( Node *pNext_ ) : pNext( pNext_ ) {
}
// ...
Node *pNext;
};
Node empty( &empty };
This empty list consists of a dummy node that has a link to itself. This is both well-defined and useful. Note that we take the address of empty, which is legal even if Node is a non-POD and hasn't been constructed yet. I don't think allowing assignment as in your your int m = m = 3;
example is directly useful, but it's hard for the language to allow mine and not also allow yours.
To see how this carries over to member constructors, consider:
struct A {
Node list;
A() : list( &list ) {}
}
Once the name is in scope, allowing assignment to and from it becomes possible too.