C++ 如何使编译器在const未一致使用时至少发出警告
假设我有一个 测试hC++ 如何使编译器在const未一致使用时至少发出警告,c++,constants,compiler-warnings,C++,Constants,Compiler Warnings,假设我有一个 测试h class Test{ public: int Func(const int a); }; Test.cpp int Test::Func(const int a){ // some code } int Test::Func(const int a){ // some code } 如果我去掉其中一个的常量,编译器仍然会编译并给出零警告。即使在GCC中启用了-Wall和-Wextra,并且在Visual studio中启用了/W4 例如Test.h c
class Test{
public:
int Func(const int a);
};
Test.cpp
int Test::Func(const int a){
// some code
}
int Test::Func(const int a){
// some code
}
如果我去掉其中一个的常量,编译器仍然会编译并给出零警告。即使在GCC中启用了-Wall和-Wextra,并且在Visual studio中启用了/W4
例如Test.h
class Test{
public:
int Func(int a);
};
Test.cpp
int Test::Func(const int a){
// some code
}
int Test::Func(const int a){
// some code
}
或测试
class Test{
public:
int Func(const int a);
};
Test.cpp两者都编译得很好
int Test::Func(int a){
// some code
}
如何使编译器能够检测头文件和源文件之间何时不一致地使用const?这些声明和定义都是相同的!在将声明与定义匹配时忽略顶级常量。所以这个组合是可以的:
class C {
void f(int);
};
void C::f(const int) {
}
因为常数不算,粗略地说。同样地
class C {
void f(int) {
}
void f(const int) {
}
};
是一个错误,因为它定义了两次相同的函数。根据标准[dcl.fct]/5 函数的所有声明应在返回类型和参数上完全一致- 类型列表。。。之后 在确定每个参数的类型时,任何类型为“T数组”或“函数返回T”的参数都是 分别调整为“指向T的指针”或“指向返回T的函数的指针”。在制作列表之后 在参数类型中,任何修改参数类型的顶级cv限定符在形成 函数类型。转换参数类型的结果列表以及省略号的存在与否 或者函数参数包是函数的参数类型列表 所以有两个声明注意:一个定义是一个声明,即使其中一个有const int a,另一个有int a,也可以一致:匹配声明时忽略顶级const
然而,顶级const在定义中很重要。如果参数为const int a,则函数体不能修改a。实际上,在头中省略const并将其包含在定义中是有意义的,因为调用方不需要知道通过值传递的参数没有被修改,这是一个实现细节。这可能就是为什么没有警告的原因。标题中有常量而定义中没有常量会很奇怪——也许应该有一个警告…哎呀,我收回了这一切。请看我的答案。编译器没有抱怨,因为函数参数的顶级常量不是函数签名的一部分,编译器会忽略它们,直到将声明与定义匹配为止。会引发异常。将打印编译器错误和警告。我已删除错误的注释。我不小心将a&读入声明中,当这些函数引用const时,const就起作用了。当他们按值接受参数时,它不会。@Praetorian期望编译器检测并抛出警告是否合理?或者它必须依赖于外部cpplint,比如linter?任何对解释它的标准的引用都会很好。我明白,当实际代码运行时,它不会有什么区别,所以它不应该是一个错误,但是编译器不应该捕获这种行为并抛出警告吗?@user3667089-代码是有效的,其含义定义良好。编译器是否应该发出警告取决于编译器供应商,显然编译器供应商并不认为这是一个重大问题,但我认为最好还是把const放在标题中,因为实现该类的内部人员仍然会阅读header@user3667089我不明白你的意思。是的,他们会读取标题,但是标题中是否存在常量毫无意义。它将作为一个文档,让开发人员知道这个变量不应该存在changed@user3667089不,这只是实现者应该决定的事情。编写函数体时,如果要更改参数,请更改它。如果你不想改变它,你就不要改变它。它在函数之外没有区别,所以没有其他人可以告诉你该做什么。