编译器的健壮性…天真

Compiler Robustness ... Naivete

本文关键字:天真 健壮性 编译器      更新时间:2023-10-16

我使用Visual Studio Professional 2012。我成功地预编译了一个类(头和源)。几天后,当编译另一个使用前一个类的类时(仅在当前头文件中),编译器捕获了缺少的引用if(this != &rhs)和分号rhs.root = nullptr;.

也许这是我的天真和缺乏知识的编译器是如何工作的,但我认为一个编译器是健壮的捕捉错误,如这些。在我看来,只有当需要特定的代码块时,编译器才觉得有必要检查它。

我读过关于即时编译的文章,了解了汇编编译器是如何先用符号再用语法执行两步编译的。我在大学里没有上过编译器构造的课程,我知道这些课程对解析器等有很好的了解。

未能捕获错误的代码段是以下移动赋值操作符:

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

编译boost变量时产生的错误,以及我的访问者类成员:

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

以及与boost序列化相关的许多其他错误。修复是,当然,纠正缺失的引用和分号,但我想了解为什么这是捕获显然只有当编译器需要触摸这段代码?

是模板类吗?

因为模板的语义分析只有在实例化时才有意义。也就是说,如果它是模板,编译器应该在缺少的分号处生成错误(语法错误),但不会在==操作符处生成错误。

用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);
}

但是当

时不编译
        x.q(x);

注释。