【问题标题】:Function template modifies parameter declared with top-level const: clang bug?函数模板修改用顶级 const 声明的参数:clang 错误?
【发布时间】:2017-01-20 19:13:25
【问题描述】:

下面的代码在 ArchLinux 上的 clang 3.8.1-1 上正确编译。

这是clang 错误吗?

gcc 对此发出正确的警告/错误。

template <class T>
struct BugReproducer{
    using size_type = typename T::size_type;

    int bug1(size_type count);
    int bug2(size_type count) const;
    static int bug3(size_type count);
};

template <class T>
int BugReproducer<T>::bug1(size_type const count){
    // this is a bug. must be not allowed
    count = 5;

    // return is to use the result...
    return count;
}

template <class T>
int BugReproducer<T>::bug2(size_type const count) const{
    // same for const method
    count = 5;
    return count;
}

template <class T>
int BugReproducer<T>::bug3(size_type const count){
    // same for static method
    count = 5;
    return count;
}



struct DummyVector{
    using size_type = int;
};



int main(){
    using BugRepr = BugReproducer<DummyVector>;

    BugRepr reproducer;

    auto a = reproducer.bug1(1);
    auto b = reproducer.bug2(1);
    auto c = BugRepr::bug3(1);

    // return is to use the result...
    return a + b + c;
}

我的编译方式如下:

[nmmm@zenbook HM3]$ clang x.cc -std=c++11 -lstdc++ -Wall -Wpedantic -Wconversion

clangc++14 - 结果相同。

[nmmm@zenbook HM3]$ clang x.cc -std=c++14 -lstdc++ -Wall -Wpedantic -Wconversion

这里是 gcc 输出:

[nmmm@zenbook HM3]$ gcc x.cc -std=c++11 -lstdc++ -Wall -Wpedantic -Wconversion
x.cc: In instantiation of ‘int BugReproducer<T>::bug1(BugReproducer<T>::size_type) [with T = DummyVector; BugReproducer<T>::size_type = int]’:
x.cc:46:28:   required from here
x.cc:13:8: error: assignment of read-only parameter ‘count’
  count = 5;
  ~~~~~~^~~
x.cc: In instantiation of ‘int BugReproducer<T>::bug2(BugReproducer<T>::size_type) const [with T = DummyVector; BugReproducer<T>::size_type = int]’:
x.cc:47:28:   required from here
x.cc:22:8: error: assignment of read-only parameter ‘count’
  count = 5;
  ~~~~~~^~~
x.cc: In instantiation of ‘static int BugReproducer<T>::bug3(BugReproducer<T>::size_type) [with T = DummyVector; BugReproducer<T>::size_type = int]’:
x.cc:48:20:   required from here
x.cc:29:8: error: assignment of read-only parameter ‘count’
  count = 5;
  ~~~~~~^~~

【问题讨论】:

  • 执行谷歌搜索“clang bug report”。不理解赞成票。请求到场外资源的方向显然是题外话。
  • 我将编辑并删除该请求。但这是一个错误吗?
  • 我不明白为什么这不是错误 - 但为什么不提交报告,看看 clang triage 怎么说?
  • 建议编辑标题以说明错误是什么(尽可能在标题空间限制内)

标签: c++ c++11 clang c++14


【解决方案1】:

是的,这是 clang 中的一个错误;提交至https://llvm.org/bugs/show_bug.cgi?id=30365

该错误的本质是类模板成员函数定义出现在类模板之外([class.mfct]/1),其参数类型取决于类模板参数,clang 使用声明的参数类型而不是定义的参数类型,它们在最顶层的 cv 限定上有所不同。简化示例:

template<class T> struct A { void f(typename T::U); };
template<class T> void A<T>::f(typename T::U const i) { i = 1; }
struct X { using U = int; };
int main() { A<X>{}.f(0); }

根据[dcl.fct]/5 A&lt;X&gt;::f 的定义中i 的类型是int const (Use of 'const' for function parameters):

5 - [...] 生成参数类型列表后,任何顶级 cv-qualifiers 修改参数 类型在形成函数类型时被删除。 [...] [ 注意: 这种转换不会影响参数的类型。 [...] — 尾注 ]

【讨论】:

  • 谢谢。你举报了吗?我还在等 bugs 帐号。
  • 是的,我已经举报了 - 添加了上面的链接。
  • 谢谢。我也无法像你那样最小化代码。
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 2018-12-23
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多