声明和定义之间常量限定符的使用不一致
Inconsistent use of const qualifier between declaration and definition
我注意到,在函数声明中的值参数上可能存在const
限定符,然后在定义中省略。这不会改变函数的签名。它实际上编译得很好。
我还注意到正则类和模板类之间的行为是不同的。此外,GCC和Clang中的处理方式也有所不同。
考虑以下代码:
template <typename T> struct A {
void f(const int);
};
template <typename T> void A<T>::f(int x) {
x = 0;
}
struct B {
void f(const int);
};
void B::f(int x) {
x = 0;
}
void f() {
A<float> a;
a.f(0);
B b;
b.f(0);
}
当我用GCC编译时,我没有得到任何错误。与Clang我得到:
test.cpp:10:7: error: read-only variable is not assignable
x = 0;
~ ^
test.cpp:26:7: note: in instantiation of member function 'A<float>::f' requested here
a.f(0);
^
海湾合作委员会在定义中倾向于使用限定词。Clang使用了声明,并且仅用于模板类A
。
我的问题是:
- 这是标准规定的还是定义的实施
- 为什么正则类和模板类的行为不同
- 为什么声明和定义之间不一致地使用
const
限定符没有错误,或者至少没有警告 - 在任何情况下这都有用吗
更新:
根据评论,这似乎是一个Clang bug。我开了一张新票。
更新:
错误已修复:
r203741 中已修复
这个行为是由标准定义的,据我所知,gcc
在这里是正确的,如果我们看看C++标准草案13.1
可忽略声明第3段说:
〔…〕-仅在存在或不存在const和/或volatile方面不同的参数声明是等效的。也就是说,在确定声明、定义或调用哪个函数时,会忽略每个参数类型的const和volatile类型说明符。
并提供了以下示例:
[ Example:
typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { /* ... */ } // definition of f(int)
int f (cInt) { /* ... */ } // error: redefinition of f(int)
—end example ]
以及一些细节澄清了这只适用于最外层的cv限定符(emphasis mine):
只有参数类型规范最外层的const和volatile类型说明符以这种方式被忽略参数类型规范中隐藏的const和volatile类型说明符意义重大,可用于区分重载函数声明123特别是,对于任何类型的T,"指针到T"、"指针到常量T"answers"指针到易失性T"都被认为是不同的参数类型,"引用到T","引用常量T",以及"引用到挥发性T.">
,据我所知,这适用于模板类中的模板函数,也适用于14.8
函数模板专业化一节,特别是14.8.3
过载分辨率,它说:
[…]完整的候选函数集包括所有合成声明和所有同名的非模板重载函数。除了13.3.3中明确指出的以外,合成声明在过载解析的剩余部分中被视为任何其他函数。144
这是一个错误,因为它阻止了合法代码,如:
/* API declaration */
void f(int);
/* Implementation */
void f(const int x) /* my business: x is my local var and I want it const */
{
}
我不敢相信有人会特意编写代码来诊断这是一个问题。
顺便说一句,海湾合作委员会对此并不抱怨,它曾经对这种情况发出过警告。也许它仍然存在:
void f(int func_ptr(void));
void f(int (*func_ptr)(void))
{
}
不过,这纯粹是风格上的不一致,没有任何作用。
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- C++:不一致的 std::p ow( 类型 ) 定义
- 访问私有嵌套类定义的行为不一致
- 声明和定义之间常量限定符的使用不一致
- 这种编译器优化不一致是否完全由未定义的行为来解释
- 类中定义的友元函数模板是否可用于查找?clang++和g++不一致
- struct和int之间clang中的重新定义不一致