迂回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
和忽略的const
types之间有区别,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
关键字。