Pedantic GCC警告:函数返回类型上的类型限定符


76

当我第一次使用GCC 4.3编译我的C ++代码时(成功地在4.1、4.0、3.4上使用-Wall -Wextra选项进行了警告的情况下成功编译了它)之后,突然出现了一系列错误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吗?


看到这个类似的问题和答案:stackoverflow.com/questions/1607188/...
litb -约翰内斯绍布

16
我以前曾经看到过这样的警告,但是,我花了几分钟试图理解代码中发生了什么。更好的错误报告可能会加快速度。而不是warning: type qualifiers ignored on function return type类似的东西warning: please don't add const qualifier when you are returning by value
Avio 2013年

@Avio为什么我们不应该const在返回值的函数中添加限定符?我们这样做是因为我们不希望此后值能够更改。
Franky

@Franky const int foo(); <-const是没用的。实际上什么也没做。const int&foo(); <-const是有意义的。
jonesmz

Answers:


102

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

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


20
它警告而不是错误并不意味着任何事情。诸如此类的其他无效代码sizeof(void)也只是警告,但显然是被禁止的。该标准不知道警告和错误之间的区别:两者都是诊断信息。
Johannes Schaub-litb

3
@litb:他说的仍然正确。当然,它们是警告的事实并不能保证它不会违反您所说的标准,但是将它们作为警告而不是错误的原因是编译器实现者不想禁止它。他们不想禁止它的原因是因为它没有违反标准。
jalf

1
是否完全违反标准?
菲利普

我认为我的第一句话很清楚,@ Philipp。看一下问题注释中提到的约翰尼斯问题:为什么返回类型上的类型限定符毫无意义?
罗伯·肯尼迪

20

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

经过大量挖掘之后,我发现禁用了警告的编译器选项:

-Wno-ignored-qualifiers

希望这可以帮助。


8
我遇到了同样的问题,最终使用-isystem代替设置Boost的include路径-I,从而抑制了Boost头引发的所有警告。
菲利普

1
@Philipp的解决方案是正确的。使用-Wno-ignored-qualifiers将影响您的代码并阻止编译器发出您创建的警告,而Philipp的解决方案将不会影响您自己的代码产生的警告。
Wond3rBoi

7

仅当您返回引用或指针(在本例中为指向常量而不是常量指针的指针)时,返回常量值才有意义,因为调用者能够修改引用(指向)的值。

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

int& getNonconstReference() {
    return _myInt;
}

应该是:

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

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


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正确性不是吗?并期望人们尝试做错了事情,因此返回类型应声明为const。并且:g ++会警告您忽略分类器,但不要忽略它。我认为,警告是关于用户采取该副本而忽略其副本上的const分类器的。但这不应该是警告,因为这绝对是正确的行为。这样做很有意义。


3
如果您添加,G ++不会在这里警告const。在const预选赛中仅仅忽略非类类型的返回值。
菲利普

1

-pedantic是否只应严格遵守ISO标准?当然取决于-std = ...


1

当声明函数返回不应该修改的对象的指针时,此警告还可以避免混淆:

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

// correct:
const Foo* bar();

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

这就是为什么编译器会在第一种情况下发出警告的原因:这是一种特殊情况,可能无法做到天真的期望。

对于现代程序设计,恕我直言,IMHO也不错,它带有const关于类类型结果的警告,因为它禁止移动语义。对于任何预想不到的小好处,这都是一笔相当大的代价。


-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关键字的情况下。


15
不,它不应该编译。的结果some_calculation是int类型的右值。您不能将其分配给非类类型的右值。
CB Bailey 2010年

1
并且如果返回值是类类型,const则正确,并且不会生成警告。
菲利普

您是否实际尝试编译此示例?GCC给出“错误:左值必须作为赋值的左操作数”,clang ++给出了“错误:表达式不可赋值”
Bulletmagnet 2015年

他可能是说==
user1032677
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.