【问题标题】:C++ and IBM compiler bug?C++ 和 IBM 编译器错误?
【发布时间】:2013-06-20 01:47:31
【问题描述】:

这里有一段非常有趣的代码。我创建它的唯一目的是演示 xlC 编译器的行为。

namespace ns {
    template<typename T> inline T f() { return T(); }
    template<> inline double f<double>() { return 0.001; } // test specialization
};
template<typename T >
class A1 {
    public: A1( const T& arg = ns::f<T>() ) {};
};
template<typename T>
class D1 {
    public: D1(T t = 0) : t_(t) {};
    private: T t_;
};
class my {
    A1< D1<int> > a;

    public: my() ;
};

//namespace ns { template<> D1<int>  f<D1<int> >() { return D1<int>(); } }

my::my() { };

void ff() {
    my m;
    A1<double> ad;
}

如果您按原样编译此代码,则会导致编译错误:

!$ xlC -c b.cpp 
"b.cpp", line 7.40: 1540-0253 (S) This use of undefined class "D1<int>" is not valid.
"b.cpp", line 22.10: 1540-1205 (I) The error occurred while converting to parameter 1 of         "A1<D1<int> >::A1(const D1<int> &)".
!$ xlC -qversion
IBM XL C/C++ for AIX, V12.1 (5765-J02, 5725-C72)

!$ uname -a
 AIX build25 1 6 00C8B3424C00 powerpc AIX

现在,如果我们取消注释以“//namespace”开头的行(这只是类型名 D1 的模板特化,编译器错误就会消失。

Gnu 编译器似乎没有问题。大家有什么想法吗?

PS。这个问题当然是在一个真实的项目中发现的,这只是一个简化的例子。在实际项目中,像 D1 这样的类有数百个。他们认为开箱即用。但是对于 xlC,我必须为每个特定情况编写专门的函数。好痛啊……

【问题讨论】:

    标签: c++ templates aix xlc


    【解决方案1】:

    xlC 对于模板的行为肯定与 gcc 不同。我在工作中的一个项目中遇到过类似的问题。

    尝试添加A1构造函数的定义。它不见了。
    xlC 很可能在编译时需要它,而 gcc 只在链接时需要它。 见GCC log

    【讨论】:

    • 我的错,你是对的。不,它没有帮助。问题来自实际项目,我花了几个小时理解它,最后想出了这个导致相同编译错误的简化代码sn-p。我无法理解的事情 - 为什么 D1 在一种情况下没有为编译器定义,而在第二种情况下,当你只是启用一个专门的功能时定义?在我看来,这个功能只是一个开销,因为 f() 默认情况下对每种类型都做同样的事情。它看起来不像是编译器错误吗?
    • 是的。您可以用您正在谈论的“简化代码 sn-p”更新您的问题吗?我仍然看不到 A1 构造函数定义。我也会尝试用 xlC 编译它。
    【解决方案2】:

    绝对是编译器错误,A1 类的默认参数 public: A1( const T&amp; arg = ns::f&lt;T&gt;() );

    在第 7 行(在定义类 D1 之前)导致对隐式实例化 D1&lt;int&gt; 的请求

    不应该在第 7 行发出请求(编译器的错误)。

    一个更简单的解决方法是在 D1的定义

    template class D1&lt;int&gt;;

    另一种解决方法是通过初始化 my 的 ctor 中的数据成员来避免使用导致不正确的隐式实例化的默认参数

    my::my() : a(ns::f&lt; D1&lt;int&gt; &gt; ()) { };

    我可以在下一个版本中修复此问题,但要在 V12.1 中修复,您需要使用服务打开一个缺陷。

    【讨论】:

    • 认为你的意思是“模板类 D1;”因为“模板类 D1;”不是模板实例化。
    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 2010-11-24
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多