Nice programing

`this-> field` 대신`this-field` 작성에 대해 경고하는 GCC 옵션이 있습니까?

nicepro 2020. 11. 27. 21:25
반응형

`this-> field` 대신`this-field` 작성에 대해 경고하는 GCC 옵션이 있습니까?


다음 코드 (악의적 인 버그 포함)는 경고없이 GCC로 컴파일됩니다. 그러나 물론 개발자 (나)가 예상 한대로 작동하지 않습니다.

#include <iostream>

struct A
{
    bool b;
    void set(bool b_) { this->b = b_; }
    bool get() const { return this-b; } // The bug is here: '-' instead of '->'
};

int main()
{
    A a;
    a.set(true);
    std::cout << a.get() << std::endl; // Print 1
    a.set(false);
    std::cout << a.get() << std::endl; // Print 1 too...
    return 0;
}

이런 종류의 오타를 피하기 위해 컴파일러 (GCC 4.8)에 어떤 경고를 추가 할 수 있습니까?

연결된 질문 : 멤버 변수 / 함수에 대한 액세스를 강제 (또는 경고)하는 옵션이 this->있습니까?


이 특정 문제는 다음에서 감지됩니다 cppcheck.

$ cppcheck --enable = all this-minus-bool.cxx 
this-minus-bool.cxx 확인 중 ...
[this-minus-bool.cxx : 7] : (경고) 의심스러운 포인터 빼기. '->'를 쓰려고 하셨나요?
(정보) Cppcheck는 모든 포함 파일을 찾을 수 없습니다 (자세한 내용은 --check-config 사용).

이것은 포함 경로가 제공되지 않았습니다. 을 추가 -I /usr/include/c++/4.8/해도 문제가 계속 감지됩니다.

this-minus-bool.cxx 확인 중 ...
[this-minus-bool.cxx] : (정보) 너무 많은 #ifdef 구성-cppcheck는 45 개 구성 중 12 개만 확인합니다. --force를 사용하여 모든 구성을 확인하십시오.
[this-minus-bool.cxx : 7] : (경고) 의심스러운 포인터 빼기. '->'를 쓰려고 하셨나요?
[/usr/include/c++/4.8/bits/ostream.tcc:335] : (스타일) '__ptr_guard'구조체에는 명시 적이 지 않은 1 개의 인수가있는 생성자가 있습니다.
[/usr/include/c++/4.8/bits/locale_classes.tcc:248] : (오류) 할당 해제 된 포인터 할당 해제 : __c

cppcheck는 앞서 언급 한 #ifdef구성을 통해 천천히 작동 합니다.

(부수적으로, 오류 local_classes.tcc는 오 탐지이지만 catch매크로 __EXCEPTIONS가 설정되지 않은 경우이 사이트 블록을 입력해서는 안된다는 점을 인식해야하기 때문에 자동화 된 도구에 대해 말하기가 매우 어렵습니다 .)

면책 조항 : cppcheck에 대한 다른 경험이 없습니다.


아니, this - b수행 포인터 연산 포인터에을 this에도 불구하고, b수있는 Being bool(유형 b암시 적으로 변환됩니다 int).

(흥미롭게도, 당신은 할 수 항상 설정 this + b포인터로 bA는 bool그래서도 좋아! 당신은 스칼라의 끝을지나 하나에 대한 포인터를 설정할 수 있기 때문에 유형이 정의되지 않은 동작의 감시인이 그 하나를 허용합니다.)

배열 경계 검사는 항상 C ++ 프로그래머의 일이었습니다.

또한 귀하의 경우에는의 사용 this이 불필요합니다. 따라서 이러한 과도한 사용을 줄이는 것이 문제를 해결하는 한 가지 방법입니다.


cppcheck@ arne-vogel이 제안한 것과는 별개로 다른 도구를 제안하여 경고 대신 더 나은 시각 자료를 제공하고 싶습니다 .

clang-format사용 하여 코드 형식 을 자동으로 지정합니다. 결과는 다음과 같을 수 있으며 (설정에 따라 다름) 주변에 추가 된 공백으로 인해 버그가 더 잘 보입니다 operator-.

struct A {
  bool b;
  void set(bool b_) { this->b = b_; }
  bool get() const { return this - b; }
};

아니요, 경고를받을 방법이 없습니다. 암시 적 변환은 비뚤어 지지만 언어에 의해 허용됩니다.

However, in this specific use case we can do better - by wrapping the bool in a wrapper class which has explicit conversions and no arithmetic operations defined.

This results in a compiler error when logically misused, which is normally seen as preferable to a warning if logical correctness is the goal.

It is interesting to note that c++17 deprecates bool::operator++ as this arithmetic is seen as evil.

example:

struct Bool
{
    explicit Bool(bool b) : value_(b) {}
    explicit operator bool() const { return value_; }
private:
    bool value_;

    // define only the operators you actually want
    friend std::ostream& operator<<(std::ostream& os, const Bool& b) {
        return os << b;
    }
};

struct X
{
    bool foo() {
        // compilation failure - no arithemetic operators defined.
        // return bool(this-b);

        // explicit conversion is fine
        return bool(b);
    }

    Bool b { true }; // explicit initialisation fine
};

참고URL : https://stackoverflow.com/questions/46319247/is-there-a-gcc-option-to-warn-about-writing-this-field-instead-of-this-field

반응형