迂回gcc警告:函数返回types的types限定符

当我第一次使用GCC 4.3编译我的C ++代码(编译成功之后, -Wall -Wextra没有带-Wall -Wextra选项的警告),我突然间发现了一堆forms为warning: type qualifiers ignored on function return type的错误warning: type qualifiers ignored on function return type

考虑temp.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是多余的,但是我很难理解为什么有必要用它产生一个警告。 还有其他地方我应该离开常客?

它不违反标准。 这就是为什么他们是警告而不是错误

事实上你是对的 – 主要的const是多余的。 编译器警告你,因为你已经添加了代码,在其他情况下可能意味着什么,但在这种情况下什么也没有,并且希望确保你以后不会失望,当你的返回值变成可以修改的时候。

编译一些使用Boost.ProgramOptions的代码时,我遇到了这个警告。 我使用 – -Werror所以警告是杀死我的构build,但因为警告的来源是在Boost的深处,我不能通过修改我的代码摆脱它。

经过多次挖掘,我发现禁用警告的编译器选项:

 -Wno-ignored-qualifiers 

希望这可以帮助。

当你返回一个引用或一个指针(在这种情况下指向常量而不是常量指针)时,返回一个常量值是有意义的,因为调用者能够修改引用的(指向的)值。

对代码的另一个评论与你的问题没有关系:我认为使用setter代替更好

 int& getNonconstReference() { return _myInt; } 

其中应该是:

 void setMyInt(int n) { _myInt = n; } 

而且,把一个const引用返回给int是没用的。 对于复制或移动更昂贵的更大的对象确实是有意义的。

有这个

struct Foo { Foo(int) {} operator bool() { return true; } };

然后

Foo some_calculation(int a, int b) { Foo result(a + b); /*...*/ return result; }

这个例子

if (some_calculation(3, 20) = 40) { /*...*/ }

编译没有警告。 当然,这是罕见的。 但是,让人们难以做错事不是正确的吗? 而且期望人们尝试的东西,这是错误的,返回types应该被声明为const。 而且:g ++警告忽略分类器,但不会忽略它。 我认为,警告是关于复制副本的用户,并忽略其副本上的常量分类器。 但这不应该是一个警告,因为这是绝对正确的行为。 这样做是有道理的。

不应该只允许严格遵守ISO标准? 取决于-std =当然…

在声明函数返回指向不应该被修改的对象的函数时,这个警告也是有用的,以避免混淆:

 // "warning: type qualifiers ignored on function return type" // as the pointer is copied. Foo* const bar(); // correct: const Foo* bar(); 

基本types结果上的const和忽略的consttypes之间有区别,types结果上的const通常会造成严重的后果。

 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. } 

这就是编译器在第一种情况下提出警告的原因:这是一个特殊情况,可能不会做到天真的预期。

对于现代编程来说,恕我直言,也会对关于类types结果的const发出警告,因为它禁止移动语义; 一个相当严重的成本,无论任何一个小想法的优势。

斯科特·迈耶斯(Scott Meyers)指出,为什么有人想要返回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返回值,上面的例子不会被编译。 那么,至less如果编译器不放弃const关键字。