以下代码在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
clang
和c++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;
~~~~~~^~~
答案 0 :(得分:5)
是的,这是clang中的一个错误;在https://llvm.org/bugs/show_bug.cgi?id=30365提交。
错误的本质是在类模板成员函数定义中出现( [class.mfct] / 1)类模板,参数类型依赖于类模板参数,clang使用声明的参数类型而不是最顶层cv-qualification中它们不同的定义的参数类型。简化示例:
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 i
定义中A<X>::f
的类型为int const
(Use of 'const' for function parameters):< / p>
5 - [...]生成参数类型列表后,修改参数的任何顶级 cv-qualifiers 在形成函数类型时删除type。 [...] [注意:此转换不会影响参数的类型。 [...] - 结束记录]