Pedantic gcc warning:在函数返回类型上输入限定符

时间:2009-07-15 21:38:01

标签: c++ const gcc-warning

当我第一次使用GCC 4.3编译我的C ++代码时,(在成功编译它之后没有带有-Wall -Wextra选项的4.1,4.0,3.4的警告)我突然遇到了一堆错误表格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吗?

8 个答案:

答案 0 :(得分:91)

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

确实你是对的 - 领先的const是多余的。编译器警告你,因为你添加的代码在其他情况下可能意味着什么,但在这种情况下没有任何意义,并且它希望确保在你的返回值结果可以修改之后你不会失望。

答案 1 :(得分:18)

在编译使用Boost.ProgramOptions的代码时遇到此警告。我使用-Werror所以警告是在杀死我的构建,但由于警告的来源是在Boost的深处,我无法通过修改我的代码来摆脱它。

经过多次挖掘后,我找到了禁用警告的编译器选项:

-Wno-ignored-qualifiers

希望这有帮助。

答案 2 :(得分:4)

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

对与您的问题无关的代码的另一个评论: 我认为最好使用setter而不是

int& getNonconstReference() {
    return _myInt;
}

应该是:

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

此外,将const引用返回给int是没用的。对于复制或移动更昂贵的更大对象来说,它确实有意义。

答案 3 :(得分:2)

有了这个

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) { /*...*/ }

在没有警告的情况下编译。当然,这种情况很少见。但是,让人们做错事情并不是一般的正确性吗?并且期望人们尝试事情,这是错误的,返回类型应该被声明为const。 并且:g ++警告忽略分类器,但不要忽略它。我认为,警告是关于获取副本并忽略副本上的const分类器的用户。但这不应该是一个警告,因为这是绝对正确的行为。这样做是有意义的。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

当声明返回指向不应修改的对象的指针的函数时,此警告也有助于避免混淆:

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

// correct:
const Foo* bar();

答案 6 :(得分:0)

基本类型结果的const与忽略的结果之间存在差异,而类类型结果的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.
}

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

对于现代编程,恕我直言,对于类类型结果的const警告也很好,因为它禁止移动语义;无论人们设想什么样的优势,都要付出相当沉重的代价。

答案 7 :(得分:-5)

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返回值,上面的示例将无法编译。好吧,至少如果编译器没有丢弃const关键字。