C++ 迂腐的 gcc 警告:函数返回类型的类型限定符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1134237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:57:05  来源:igfitidea点击:

Pedantic gcc warning: type qualifiers on function return type

c++constgcc-warning

提问by Seth Johnson

When I compiled my C++ code with GCC 4.3 for the first time, (after having compiled it successfully with no warnings on 4.1, 4.0, 3.4 with the -Wall -Wextraoptions) I suddenly got a bunch of errors of the form warning: type qualifiers ignored on function return type.

当我第一次用 GCC 4.3 编译我的 C++ 代码时,(在使用选项成功编译它之后,在 4.1、4.0、3.4 上没有警告-Wall -Wextra)我突然收到了一堆表单错误warning: type qualifiers ignored on function return type

Consider temp.cpp:

考虑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:

运行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 am doing wrong that violates the C++ standard? I suppose that when returning by value, the leading constis superfluous, but I'm having trouble understanding why it's necessary to generate a warning with it. Are there other places where I should leave off the const?

有人能告诉我我做错了什么违反了 C++ 标准吗?我想当按值返回时,前导const是多余的,但我无法理解为什么有必要用它生成警告。还有其他地方我应该放弃 const 吗?

回答by Rob Kennedy

It doesn't violate the standard. That's why they're warningsand not errors.

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

And indeed you're right — the leading constis superfluous. The compiler warns you because you've added code that in other circumstances might mean something, but in this circumstance means nothing, and it wants to make sure you won't be disappointed later when your return values turn out to be modifiable after all.

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

回答by ccaughie

I encountered this warning when compiling some code that uses Boost.ProgramOptions. I use -Werrorso the warning was killing my build, but because the source of the warning was in the depths of Boost I couldn't get rid of it by modifying my code.

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

After much digging I found the compiler option that disables the warning:

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

-Wno-ignored-qualifiers

Hope this helps.

希望这可以帮助。

回答by Brahim

Returning a constant value only makes sense when you return a reference or a pointer(in this case pointer to constant and not a constant pointer) because the caller is able to modify the referenced (pointed to) value.

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

Another comment on the code not related to your question: I think it's better to use a setter instead of

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

int& getNonconstReference() {
    return _myInt;
}

Which will should be:

这应该是:

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

Moreover, it's useless to return a const reference to an int. It does make sense for a bigger object whose copy or move is more expensive.

此外,返回对 int 的 const 引用是没有用的。对于更大的对象,其复制或移动的成本更高,这确实有意义。

回答by mcbulba

Having this

有这个

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

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

and that

然后

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

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

the example

这个例子

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

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

compiles without a warning. Of course, this is rare. But isn't const correctness about making it hard for people to do things wrong? And with the expectation that people try things, that are wrong, the return type should be declared const. And: g++ warns about ignoring the classifier, but does not ignore it. I think, the warning is about users that take the copy and ignore the const classifiers on their copy. But that should not be a warning, because this is absolutely correct behavior. And it makes sense to do this.

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

回答by Steve

Shouldn't -pedantic only allow strict adherence to the ISO standard? Depending on -std= of course...

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

回答by Luchs

This warning is also useful to avoid confusion when declaring functions returning pointers to objects which should not be modified:

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

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

// correct:
const Foo* bar();

回答by Cheers and hth. - Alf

There is a difference between conston a basic type result, where it's ignored, and conston a class type result, where it generally wreaks havoc.

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

This is why the compiler warns in the first case: it's a special case, that may not do what one na?vely could expect.

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

For modern programming it would IMHO be nice also with a warning about conston class type result, since it prohibits move semantics; a rather severe cost for whatever little advantage one envisioned.

对于现代编程,恕我直言,const对类类型结果的警告也很好,因为它禁止移动语义;对于任何一个人预想的小优势来说,都是相当严重的代价。

回答by user321269

Scott Meyerspointed out that there's pretty good reason why someone would want to return constvalues. Here's an example:

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

}

Do you see what I did wrong? This code is absolutely correct and should compile. The problem is that the compiler didn't understand that you intended tocompare instead of assignthe value 40.

你看到我做错了什么吗?这段代码是绝对正确的,应该可以编译。问题是编译器不明白您打算比较而不是分配value 40

With a constreturn value the above example won't compile. Well, at least if the compiler doesn't discard the constkeyword.

使用const返回值,上面的示例将无法编译。好吧,至少如果编译器不丢弃const关键字。