C++

[c++] cppcheck와 visual studio MFC

달나라외계인 2024. 4. 18. 16:40

cppcheck는 정적분석툴 (static analysis tool) 중에 하나로 cross platform이며, 동시에 오픈소스로 제공되는 툴입니다. 이번에 코드 퀄리티를 위해 정적분석툴 도입을 검토하게 되어 정적분석툴을 조사하게 되었고, 그중 하나인 cppcheck에 대해 글을 적어 보려 합니다. cppcheck는 다음의 사이트에서 받아 보실 수 있습니다.

 

https://cppcheck.sourceforge.io/

 

Cppcheck - A tool for static C/C++ code analysis

Cppcheck is a static analysis tool for C/C++ code. It provides unique code analysis to detect bugs and focuses on detecting undefined behaviour and dangerous coding constructs. The goal is to have very few false positives. Cppcheck is designed to be able t

cppcheck.sourceforge.io

 

  크로스 플랫폼이라 사용은 같겠지만, 혹시 모르니 저는 windows 버전을 받아서 visual studio와 함께 테스트 해보았음을 말씀 드립니다.

  설치시 따로 환경을 커스터마이징 하지 않았다면 C:\Program Files\Cppcheck 폴더에 프로그램이 설치됩니다. 해당 폴더에는 실행할 수 있는 파일이 cppcheck.execppcheckgui.exe가 있는데 cppcheck.exe는 console용 프로그램이며 cppcheckgui.exe는 cppcheck를 gui 환경에서 사용해 볼 수 있는 프로그램입니다. cppcheck.exe는 IDE (windows에서는 visual studio 등)과 연결해서 사용하면 편리하고, 독립적으로 사용해 보고 싶으시면 cppcheckgui.exe를 사용하는 것이 편리할 거라고 생각합니다. 여기서는 cppcheckgui.exe를 설명 드리도록 하겠습니다.

 

  먼저 cppcheck 프로그램 실행 후 파일-새 프로젝트 파일을 선택합니다.

  그럼 프로젝트 파일을 어디다 만들지 선택하는 파일 다이얼로그가 나오는데 원하시는 적당한 위치에 만들어 줍니다. 추후 프로젝트 파일을 사용하시면 동일한 위치의 코드를 검사하는데 매번 설정할 필요가 없어질 것입니다. cppcheck를 수행하면 그 결과 파일이 하위폴더에 만들어지므로 새로운 폴더를 만들고 진행하시길 권장합니다. 파일을 선택하고 나면  프로젝트 파일에 관한 설정 다이얼로그가 뜹니다. 여기서 'Paths and Defines' 탭을 선택후 Import Project를 수행합니다.

그럼 visual studio 파일인 .vcxproj (프로젝트) 파일이나 .sln (솔루션)을 선택하는 파일다이얼로그가 뜹니다. 원하는 visual studio 프로젝트로 가서 해당 파일을 엽니다. 그리고 OK 버튼을 눌러봅니다. 그러면 build를 위해 아까 cppcheck 프로젝트 하위 폴더에 test-cppcheck-build-dir 폴더를 만들겠냐고 물어봅니다. 만약 no를 한다면 임시로 어딘가에 temp 폴더를 만들고 진행할 겁니다. 하지만 MFC 프로젝트를 선택하셨다면 다음과 같은 오류가 발생하며 진행이 되지 않습니다.

  MFC에는 MFC에서 사용되는 많은 매크로 파일들이 있는데 이것들을 Visual Studio 프로젝트 위치에서 알아서 라이브러리를 읽어서 검사해 주지 못합니다. MFC 라이브러리용 설정이 먼저 필요합니다. MFC 라이브러리 설정은 설치시 함께 제공하고 있습니다. 만약 설치된 목록에 없는 라이브러리를 사용하고 있다면 라이브러리용 설정 파일을 찾아야 할 것입니다. 다시 세팅을 위해 프로젝트 설정으로 들어가야 합니다. 파일-프로젝트 파일 편집으로 들어가면 다시 프로젝트 설정으로 들어 가실 수 있습니다.

  이번에는 'Types and Functions' 탭으로 이동하신 후 library중 mfc를 선택하여 준 후 OK를 눌러 줍니다.

 

  또한 C++ 표준에 따라 코드가 달라지므로 다음과 같이 이를 선택해 주는 것이 좋습니다. 저는 c++ 17 버전을 사용하기에 다음의 위치에서 이것을 선택해 줬습니다.

 

  그럼 다시 분석을 해봅니다.

  검사된 파일목록의 펼치기 버튼을 누르면 파일별 상세 분석 내용이 나옵니다. 그중에 이번에는 ''Include file: <vector> not found. Please note: Cppcheck does not need standard library headers to get proper results." 라는 메시지가 눈에 거슬립니다. vector 라이브러리를 지정할 필요는 없다지만 경고가 뜨기에 보기 좋지 않습니다. 다시 프로젝트 설정으로 들어 가셔서 'Warning options' 탭에 들어가신 후 suppress에 missingIncludeSystem을 추가해 줍니다.

  또 다른 방법으로는 다음과 같이 해당 메시지 위에서 마우스 오른쪽을 누른 후 'Suppress selected id(s)'을 누르셔도 됩니다. 이렇게 보고 싶지 않은 메시지들은 감춥니다.

  참고로 치명적인 에러 부분만 보고 싶다면 다음의 아이콘으로 보고 싶은 레벨의 에러만 볼 수도 있습니다.

 

  다음은 이 블로그 글을 쓰면서 제 코드를 돌린 후 'Possible null pointer dereference: package' 경고를 발견한 예입니다.

void Link(SerializerEx& serializer, const std::shared_ptr<Data::Package> package) const {
  int64_t time_stamp = -1;
  int32_t data_count = 0;
  if (package != nullptr) {
    time_stamp = package->GetTimeStamp();
    data_count = package->GetCount();
  }

  serializer.Serialize(time_stamp);
  serializer.Serialize(data_count);

  for (int32_t index = 0; index < data_count; index++) {
    auto& item_result = package->GetAt(index); // <= 경고부분

 

  Link라는 함수는 package라는 클래스는 Save나 Load하는 함수인데 package가 nullptr인 경우 해당 line에서 nullptr로 접근될 수 있음을 알려준 것입니다. 정적분석은 종종 잘못된 경고를 하기도 하지만 위와 같이 일부 실수를 방지해 주는 역활을 함으로 코드 변경 후에는 수시로 확인을 해주는 것이 좋습니다.

 

현재까지 사용해 보면서 생긴 문제

* 큰 프로젝트 분석중 클릭하다보면 프로그램이 죽는 경우가 발생함

* 현재 최신버전 2.13.0 addon의 MISRA 2012 rule 사용시 gui 에서 제대로 동작하지 않는 문제 발생 (링크)