c++c++11visual-c++visual-studio-2012

Compiler Robustness ... Naivete


I use Visual Studio Professional 2012. I pre-compiled a class (header and source) successfully. Days later, when compiling another class (for the moment header only) that is utilizing the previous one, the compiler caught a missing reference if(this != &rhs) and semicolon rhs.root = nullptr;.

Perhaps it is my naivete and lack of knowledge about how compilers work but I thought a compiler was robust to catch errors such as these. It appeared to me that only when a specific block of code was required did the compiler feel the need to check it.

I have read about just-in-time compilation and learned how assembly compilers perform a two-pass compilation with symbols first and then syntax. I have not taken a course in compiler construction at my university and I know such courses give great insight into parsers, etc.

The code section where it failed to catch the error is this move assignment operator:

Tree &operator=(Tree &&rhs) 
{ 
    if(this != rhs)    <--------- no reference to the rhs
    { 
        root = std::move(rhs.root); 
        rhs.root = nullptr      <----------- no semicoln
    } 
    return *this; 
}

The errors were generated while compiling boost variant, as well as my visitor class member:

bool operator() (Tree<std::string>& tree) const {
    return tree.load(tree);
}

as well as a host of other errors related to boost serialization. The fix was to, of course, correct the missing reference and semicolon but I want to understand why this was caught apparently only when the compiler needed to touch this code?


Solution

  • Is it a template class?

    Because semantic analysis of templates makes only sense when they are instantiated. That is, if it is a template, the compiler should generate an error at the missing semicolon (syntactic error), but not at the == operator.

    The following code compiles with g++:

    template<typename T>
    struct A {
            void q(A &a) {
                    if (this == a) {}
            }
    
    };
    
    int main(int argc, char **argv) {
            A<int> x;
            //x.q(x);
    }
    

    But doesn't compile when

            x.q(x);
    

    is uncommented.