ProgramingTip

현명한 gcc 경고 : 함수 반환 유형에 대한 유형 한정자

bestdevel 2020. 11. 11. 20:27
반응형

현명한 gcc 경고 : 함수 반환 유형에 대한 유형 한정자


처음으로 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를 생략해야 할 다른 곳이 있습니까?


표준을 위반하지 않습니다. 이것이 오류가 아니라 경고 인 이유 입니다.

그리고 실제로 당신 말이 맞습니다 const. 선두 는 있습니다. 컴파일러는 다른 상황에서는 의미가있을 수있는 코드를 추가 할 수 있기 때문에 경고가 상황에서는 아무 의미가 있지만 나중에 반환 값이 수정 가능한 경우 판명 때 더 실망하지 않습니다.


Boost.ProgramOptions를 사용하는 일부 코드를 사용할 때이 경고가 발생했습니다. 내가 사용 -Werror경고 내 빌드를 죽이고 그래서, 그러나 경고의 소스가 부스트의 깊이에 있었기 때문에 나는 내 코드를 수정하여 제거합니다.

많은 파고 끝에 경고를 춤추는 컴파일러 옵션을 찾았습니다.

-Wno-ignored-qualifiers

도움이 되셨기를 바랍니다.


상수 값을 반환하는 것은 참조 또는 포인터 (이 경우 상수 포인터가 아닌 상수에 대한 포인터)를 반환 할 때만 의미가 있습니다. (지정된) 값을 가지고 있기 때문입니다.

귀하의 질문과 관련이없는 코드에 대한 또 다른 의견 : 대신 세터를 사용하는 것이 더 낫다고 생각합니다.

int& getNonconstReference() {
    return _myInt;
}

다음 중 어느 것이되어야합니다.

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

또한 int에 대한 const 참조를 반환하지 않습니다. 복사 또는 이동 비용이 더 많은 더 큰 개체에 적합합니다.


제시 가지고

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 분류자를 무시하는 사용자에 대한 것입니다. 그러나 이것은 절대적으로 올바른 행동이기 때문에 경고가되어서는 안됩니다. 그리고 이것을하는 것이 합리적입니다.


-pedantic은 ISO 표준에 대한 엄격한 준수 만 허용하면 안됩니까? 물론 -std =에 따라 ...


이 경고는 수정해서는 안되는 객체에 대한 포인터를 반환하는 함수를 선언 할 때 혼동을 피하는데도 유용합니다.

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

// correct:
const Foo* bar();

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이동 의미론을 금지하기 때문에 클래스 유형 결과에 대한 경고와 함께 좋을 것입니다 . 아무리 작은 이점을 구상하더라도 상당히 심각한 비용입니다.


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.

A를 const반환 값 위의 예는 컴파일되지 않습니다. 글쎄, 적어도 컴파일러가 const키워드를 버리지 않는다면 .

참고 URL : https://stackoverflow.com/questions/1134237/pedantic-gcc-warning-type-qualifiers-on-function-return-type

반응형