首页 文章

模板编译:gcc vs VS2010

提问于
浏览
1

从书中 - C模板:David完整指南,Nicolai

因此,模板被编译两次:没有实例化,检查模板代码本身的语法是否正确 . 发现语法错误,例如缺少分号 . 在实例化时,检查模板代码以确保所有调用都有效 . 发现无效调用,例如不支持的函数调用 .

保持第一点,我写道 -

template<typename T>
void foo( T x)
{
   some illegal text
}

int main()
{
   return 0;
}

它在Visual Studio 2010上构建正常,没有关闭优化的任何警告 . 怎么样,it failed on gcc-4.3.4 . 哪一个符合C标准?即使没有模板实例化,模板代码也必须编译吗?

2 回答

  • 0

    有问题的程序格式不正确,但C标准在这种情况下不需要诊断,因此Visual Studio和GCC都以兼容的方式运行 . 从C03标准的§14.6/ 7(强调我的):

    了解哪些名称是类型名称允许检查每个模板定义的语法 . 不能为可以生成有效特化的模板定义发出诊断 . 如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义格式错误,无需诊断 . 如果非依赖名称中使用的类型在定义模板但在完成实例化时完成,并且该类型的完整性影响程序是否良好时,则不完整形成或影响程序的语义,该程序是不正确的;无需诊断 . [注意:如果实例化模板,将根据本标准中的其他规则诊断错误 . 确切地说,这些错误被诊断出来是一个实施质量问题 . ] [例子:int j;
    template <class T> class X {
    // ...
    void f(T t,int i,char * p)
    {
    t = i; //如果X :: f被实例化,则被诊断出来
    //并且对t的赋值是错误的
    p = i; //即使X :: f也可以被诊断出来
    //没有实例化
    p = j; //即使X :: f也可以被诊断出来
    //没有实例化
    }
    void g(T t){
    ; //即使X :: g是,也可能被诊断出来
    //没有实例化
    }
    };

    • 末端的例子]
  • 7

    你正在看的这本书似乎(主要)反映了作者关于编译器如何工作的观察,而不是标准的要求 . 标准并没有真正说明为编译器提供额外的宽大处理,因为它没有实例化 .

    与此同时,本书是正确的,编译器确实可以实例化一些东西 . 例如,您可以使用依赖名称作为函数的名称(或者像函数一样调用它 - 无论如何 - 如果它是仿函数,那么它也会很好) . 如果你在一个函数的类上实例化该模板,那很好 . 如果你在一个实际上是 int 的类上实例化它,试图调用它无疑会失败 . 直到你've instantiated it, the compiler can'告诉我哪个是哪个 .

    这是 concepts 真正打算添加到C的很大一部分 . 您可以直接指定(例如)模板X将像函数一样调用 T::y . 然后编译器可以将模板的内容与概念中的声明进行比较,并确定模板的主体是否符合概念中的声明 . 在另一个方向上,编译器只需要将类(或其他)与概念进行比较,以确定实例化该模板是否有效 . 如果它不起作用,它可以直接报告错误作为违反相关概念(因为它现在,它试图实例化模板,并且你经常得到一些奇怪的错误信息,表明真正的问题很糟糕,如果有的话) .

相关问题