Pedantic gcc警告:函数返回类型上的类型限定符 当我第一次用GCC 4.3编译我的C++代码时(在成功编译后没有4.1、4、3.4的警告,使用 -Walth-WoTe>代码>选项),我突然得到了一组形式错误:代码>警告:函数返回类型被忽略的类型限定符。
考虑Pedantic gcc警告:函数返回类型上的类型限定符 当我第一次用GCC 4.3编译我的C++代码时(在成功编译后没有4.1、4、3.4的警告,使用 -Walth-WoTe>代码>选项),我突然得到了一组形式错误:代码>警告:函数返回类型被忽略的类型限定符。,c++,constants,gcc-warning,C++,Constants,Gcc Warning,考虑温度cpp: class Something { public: const int getConstThing() const { return _cMyInt; } const int getNonconstThing() const { return _myInt; } const int& getConstReference() const { return _myInt; }
温度cpp
:
class Something
{
public:
const int getConstThing() const {
return _cMyInt;
}
const int getNonconstThing() const {
return _myInt;
}
const int& getConstReference() const {
return _myInt;
}
int& getNonconstReference() {
return _myInt;
}
void setInt(const int newValue) {
_myInt = newValue;
}
Something() : _cMyInt( 3 ) {
_myInt = 2;
}
private:
const int _cMyInt;
int _myInt;
};
运行g++temp.cpp-Wextra-c-o blah.o
:
temp.cpp:4: warning: type qualifiers ignored on function return type
temp.cpp:7: warning: type qualifiers ignored on function return type
有人能告诉我违反C++标准的做法是什么吗?我认为当按值返回时,前导的
常量是多余的,但是我很难理解为什么需要用它生成警告。还有其他地方我应该停止const吗?它没有违反标准。这就是为什么它们是警告而不是错误
事实上,你是对的,前导的常量是多余的。编译器警告您,因为您已经添加了代码,在其他情况下可能有意义,但在这种情况下没有意义,并且它希望确保您在返回值最终可修改时不会失望。我在编译一些使用Boost.ProgramOptions的代码时遇到了此警告。我使用了-Werror
,因此警告正在扼杀我的构建,但由于警告源位于Boost的深处,我无法通过修改代码来消除它
经过深入挖掘,我找到了禁用警告的编译器选项:
-Wno忽略的限定符
希望这能有所帮助。指出,有人想要返回const
值是有充分理由的。下面是一个例子:
int some_calculation(int a, int b) { int res = 0; /* ... */ return res; }
/* Test if the result of the calculation equals 40.*/
if (some_calculation(3,20) = 40)
{
}
你知道我做错了什么吗?这段代码绝对正确,应该编译。问题是编译器不理解您打算比较而不是赋值40
使用const
返回值,上述示例将无法编译。好吧,至少如果编译器没有丢弃const
关键字
struct Foo{Foo(int){}运算符bool(){return true;}}代码>
那
Foo一些计算(inta,intb){Foo结果(a+b);/*…*/返回结果;}
榜样
if(一些计算(3,20)=40){/*…*/}
编译时没有警告。当然,这是罕见的。但const correction不就是让人们很难做错事吗?由于期望人们尝试错误的事情,返回类型应该声明为const。
并且:g++警告忽略分类器,但不会忽略它。我认为,警告是关于用户,他们拿走了副本,却忽略了副本上的常量分类器。但这不应该是一个警告,因为这是绝对正确的行为。这样做是有道理的。学究不应该只允许严格遵守ISO标准吗?根据-std=当然…在声明函数返回指向不应修改的对象的指针时,此警告也有助于避免混淆:
/“警告:函数返回类型上的类型限定符被忽略”
//当指针被复制时。
Foo*const-bar();
//正确:
常量Foo*bar();
只有在返回引用或指针(在本例中是指向常量的指针,而不是常量指针)时,返回常量值才有意义,因为调用方可以修改引用(指向的)值
与您的问题无关的代码的另一条评论:
我认为最好用二传手而不是
int& getNonconstReference() {
return _myInt;
}
其中应包括:
void setMyInt(int n) {
_myInt = n;
}
此外,将常量引用返回到int是没有用的。对于复制或移动成本更高的较大对象来说,这是有意义的。基本类型结果上的常量被忽略,而类类型结果上的常量通常造成严重破坏
namespace i {
auto f() -> int const { return 42; }
void g( int&& ) {}
}
namespace s {
struct S {};
auto f() -> S const { return {}; }
auto g( S&& ) {}
}
auto main() -> int
{
{ using namespace i; g( f() ); } // OK
{ using namespace s; g( f() ); } // !The `const` prevents this.
}
这就是编译器在第一种情况下发出警告的原因:这是一种特殊情况,可能无法达到人们天真的期望
对于现代编程来说,最好在类类型结果上添加一个关于const
的警告,因为它禁止移动语义;无论预想到什么样的小优势,这都是一个相当严重的代价。看看这个类似的问题和答案:我以前见过类似的警告,不过,我花了几分钟试图理解代码中发生了什么。也许更好的错误报告会加快速度。而不是警告:在函数返回类型上忽略类型限定符
类似于警告:当您按值返回时,请不要添加常量限定符
@Avio为什么不将常量
限定符添加到返回值的函数中?我们这样做是因为我们不希望以后值能够更改。@Franky const int foo();它发出警告而不是错误并不意味着什么。其他无效代码,如sizeof(void)
也只是发出警告,但显然是禁止的。标准不知道警告和错误之间的区别:两者都是诊断。@litb:他说的仍然是正确的。当然,它们是警告的事实并不能保证它不会像您所说的那样违反标准,但是它们发出警告而不是错误的原因是编译器实现者不想禁止它。他们不想禁止它的原因是因为它没有违反标准。它完全违反了标准吗?我想我的第一句话对此相当清楚,@Philipp。看看Johannes在问题评论中提到的问题:不,它不应该编译。some\u计算的结果是int类型的右值。您不能分配给非类类型的右值。如果返回值是类类型,则const
是正确的,不会生成wa