`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
포인터로 b
A는 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
};
'Nice programing' 카테고리의 다른 글
내 모든 디스크 공간을 차지하는 Docker 컨테이너 로그 (0) | 2020.11.27 |
---|---|
ErrorCode = '0x80004005 : 80008083으로 인해 IIS에서 .NET Core 앱을 시작할 수 없음 (0) | 2020.11.27 |
웹 사이트 스크린 샷을 만드는 명령 줄 프로그램 (Linux) (0) | 2020.11.27 |
데이터베이스에서 일반 텍스트 암호 암호화 / 해싱 (0) | 2020.11.27 |
SQL Server Express로 매일 백업을 예약하려면 어떻게해야합니까? (0) | 2020.11.27 |