GCC 3.0印象记

虫虫&beyond_ml

编者按:GCC 3.0正式发布了,小编我委托虫虫和beyond_ml测试一下。由虫虫列出测试项目,编写测试程序;beyond_ml在Redhat 6.0上分别用GCC 2.9x和GCC 3.0测试。如果您有什么新发现,不妨发email告诉我们。

2001-6-18 GCC 3.0正式发布(http://gcc.gnu.org)。

从1999年4月开始,GCC的含义从GNU C Compiler变成了GNU Compiler Collection,支持C、C++、Objective C、Chill、Fortan和Java等语言。其中C++编译器G++当然是我们关注的焦点。从GCC网站的介绍中可以看出,G++作了不少改进,更好地支持C++标准。我们将选出相关的内容逐一评论。我们对GCC 3.0的总体印象是,有不少改进,但“革命尚未成功”,还得加把劲儿。

支持使用using从基类中引入成员函数

这是GCC老版本的一个大bug了。例如,下面这段程序虽然符合C++标准,但在以前版本的G++中不能被编译。

struct A
{
    void f() {}
};
struct B: A
{
    using A::f;
    void f(int) {}
};

void main()
{
    B b;
    b.f();
}

在GCC 3.0中,这段程序就能够顺利通过了,可以算是一个进步。(编者注:GCC 3.0处理虚拟函数仍然失当,bug依旧,《钻穿牛角尖:using声明vs.虚函数》一文中有详细的分析。)

加强对嵌套类型的存取控制

看看这个程序。

class X
{
private:
    typedef int Y;
};


void main()
{
    X::Y a;
}

按标准,这样的程序显然是错误的,X::Y不可访问。然而在GCC 2.9x上却能编译通过。GCC 3.0加强了对嵌套类型的管理,这个问题已经不复存在。

下面这段程序来自C++标准ISO/IEC 14882第184页。

class C
{
    class A{};
    A *p;
    class B : A
    {
        A       *q;
        C::A    *r; //error
        B       *s;
        C::B    *t; //error
    };
};

标记为error的两行按标准应该出错,然而在GCC 2.9x和3.0上均编译通过,可见GCC对嵌套类的访问控制还不尽如人意。

改进了名字粉碎机制

这是编译器编译、连接的具体实现,我们就不做测试了。

某些以前可以编译通过的无效转换现在都将被拒绝

在帮助文件里特别提到了函数指针的转换,GCC 3.0比以前更为严格。可惜我们没有发现好的例子。不过以前函数指针转换的一个大bug,现在依然没有修复。

#include
template void test(C f) {}
void main()
{
    test(&std::vector::push_back);
}

上面class C代表的是一个模板类的成员函数指针。在GCC 2.9x和GCC 3.0中,我们都会得到'no matching function for call to `test ({unknown type})'的编译错误,而这是一个正确的程序。




©2000-2002 C-View.ORG All Rights Reserved.