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

发布于 2024-07-29 01:19:15 字数 1012 浏览 7 评论 0原文

当我第一次使用 GCC 4.3 编译 C++ 代码时(使用 -Wall -Wextra 选项在 4.1、4.0、3.4 上成功编译后没有警告)我突然得到了一堆形式为警告:函数返回类型上忽略类型限定符的错误。

考虑 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 吗?

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 -Wextra options) I suddenly got a bunch of errors of the form 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 am doing wrong that violates the C++ standard? I suppose that when returning by value, the leading const is 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

跨年 2024-08-05 01:19:15

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

事实上,你是对的 - 领先的 const 是多余的。 编译器会向您发出警告,因为您添加的代码在其他情况下可能有意义,但在这种情况下毫无意义,并且它希望确保您稍后在返回值可修改时不会感到失望。

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

And indeed you're right — the leading const is 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.

时光磨忆 2024-08-05 01:19:15

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

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

-Wno-ignored-qualifiers

希望这会有所帮助。

I encountered this warning when compiling some code that uses Boost.ProgramOptions. I use -Werror so 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.

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

-Wno-ignored-qualifiers

Hope this helps.

许仙没带伞 2024-08-05 01:19:15

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

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

int& getNonconstReference() {
    return _myInt;
}

Which will should be:

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

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

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

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.

稚然 2024-08-05 01:19:15

有了这个

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

以及

Foo some_calculation(int a, int b) { Foo result(a + b); /*...*/ 返回结果; }

示例

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

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

Having this

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

and that

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

the example

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.

山有枢 2024-08-05 01:19:15

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

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

忆依然 2024-08-05 01:19:15

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

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

// correct:
const Foo* bar();

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();
悲欢浪云 2024-08-05 01:19:15

基本类型结果上的 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 的警告会很好,因为它禁止移动语义; 对于人们所设想的哪怕一点点好处,都会付出相当惨重的代价。

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

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 const on class type result, since it prohibits move semantics; a rather severe cost for whatever little advantage one envisioned.

原野 2024-08-05 01:19:15

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 关键字的话。

Scott Meyers pointed out that there's pretty good reason why someone would want to return const values. Here's 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 didn't understand that you intended tocompare instead of assign the value 40.

With a const return value the above example won't compile. Well, at least if the compiler doesn't discard the const keyword.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文