Pedantic gcc warning: enter return type qualifiers

When I first compiled my C ++ code using GCC 4.3 (after he compiled it successfully without warnings on 4.1, 4.0, 3.4 with the -Wall -Wextra ), I unexpectedly got a bunch of warning: type qualifiers ignored on function return type .

Consider 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; }; 

Running 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 

Can someone tell me what I'm doing wrong that violates the C ++ standard? I believe that when returning by value, the leading const superfluous, but it's hard for me to understand why it needs to create a warning. Are there other places where I should leave const?

+53
c ++ const gcc-warning
Jul 15 '09 at 21:38
source share
8 answers

This does not violate the standard. This is why they are warnings, not errors.

And indeed, you are right - the leading const superfluous. The compiler warns you because you added code that in other circumstances could mean something, but in this case does not mean anything, and he wants to make sure that you will not be disappointed later when your return values ​​turn out to be modifiable in the end .

+72
Jul 15 '09 at 21:43
source share
— -

I came across this warning when compiling code that uses Boost.ProgramOptions. I use -Werror , so a warning kills my assembly, but since the source of the warning was deep in Boost, I could not get rid of it by changing my code.

After searching repeatedly, I found a compiler option that disables the warning:

 -Wno-ignored-qualifiers 

Hope this helps.

+17
Aug 19 '09 at 9:34
source share

Returning a constant value makes sense only when you return a link or pointer (in this case, a pointer to a constant, not a pointer to a constant), since the caller can change the reference (specified) value.

Another code comment not relevant to your question: I think it's better to use a setter instead

 int& getNonconstReference() { return _myInt; } 

Which should be:

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

In addition, it is useless to return a constant reference to int. This makes sense for a larger facility whose copy or move is more expensive.

+4
May 19 '15 at 14:59
source share

Having it

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

So what

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

example

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

compiles without warning. Of course, this is rare. But is not a correct statement in order to make people do something wrong? And with the expectation that people are trying to do something, this is not true, the return type should be declared as const. And: g ++ warns about ignoring the classifier, but does not ignore it. I think a warning about users who take a copy and ignore const classifiers on their copy. But this should not be a warning, because this is absolutely correct behavior. And it makes sense to do it.

+2
Jul 13 '10 at 11:32
source share

Is it possible - Abkhazism to allow strict adherence to the ISO standard? Depending on -std = of course ...

+1
Feb 13 '11 at 23:55
source share

This warning is also useful to avoid confusion when declaring functions that return pointers to objects that should not be changed:

 // "warning: type qualifiers ignored on function return type" // as the pointer is copied. Foo* const bar(); // correct: const Foo* bar(); 
+1
Apr 07 '14 at 12:06 on
source share

There is a difference between const for the result of the base type, where it is ignored, and const for the result of the class type, where it usually causes chaos.

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

This is why the compiler warns in the first case: this is a special case that might not do what you might naively expect.

For modern programming, it would also be nice to warn const about the result of a class type, since it prohibits the semantics of movement; pretty harsh cost for any small advantage that was provided.

0
Mar 29 '16 at 10:31
source share

Scott Meyers pointed out that there is a pretty good reason why someone wants to return const values. Here is an example:

 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) { } 

Do you see what I did wrong? This code is absolutely correct and should compile. The problem is that the compiler did not understand that you intended to compare 40 instead of assigning .

With a return value of const , the above example will not compile. Well, at least if the compiler does not drop the const keyword.

-5
Apr 20 '10 at 12:16
source share



All Articles