﻿# PVS\-Studio vs CodeLite: a battle for the perfect code

How to improve the quality and reliability of a codebase? One of the answers to this question is to use static analysis\. In this article, we are going to check how this methodology can improve the codebase quality\. We will use the CodeLite project as an example\.

![1065_CodeLite/image1.png](https://import.viva64.com/docx/blog/1065_CodeLite/image1.png)

## About CodeLite

CodeLite is a free integrated development environment \(IDE\) for various programming languages including C, C\+\+, PHP, and JavaScript\. It is designed to simplify the software development process; it offers many features and tools\.

Key features of CodeLite:

* Code editor: CodeLite provides a convenient and powerful code editor with syntax highlighting, autocomplete, fast navigation capabilities, and other useful tools\.
* Debugger: the IDE includes a debugger that allows you to monitor program execution, set breakpoints, and analyze the state of variables\.
* Build system: CodeLite supports several build systems, including Make, CMake, and others\. It makes compilation and project building easier\.
* Git integration: the IDE has built\-in support for the Git version control system\. It allows developers to easily work with Git repositories directly from the development environment\.
* Additional extensions support: CodeLite supports plugins that allow users to extend the functionality of the IDE according to their own needs\.
* Portability: CodeLite is available for Windows, macOS, and Linux operating systems, making it a great choice for cross\-platform developers\.

CodeLite is an open\-source project\. It allows programmers to take part in its development and to help improve the IDE\. It is continually updated and enhanced to provide powerful tools for programmers\.

A lot of time has passed since we published the last [article](https://pvs-studio.com/en/blog/posts/cpp/0443/) about CodeLite's check in the PVS\-Studio blog\. Can't wait to find out what kind of new bugs we are going to find\.

## Analysis results

The analyzer issued a lot of warnings while checking CodeLite [17\.0\.0](https://github.com/eranif/codelite/tree/17.0.0)\. As a result, this article will only cover those code fragments that caught my attention while I was going over some of the warnings\. If you are the project authors and you find this article interesting, you may check the project yourself\. This way you can have a closer look at the list of warnings\. You may use a trial version\. If you enjoy our tool and would like to use it on a regular basis, there is a free license available for open\-source projects\.

**Fragment N1**

The analyzer warning: [V554](https://pvs-studio.com/en/docs/warnings/v554/) Incorrect use of unique\_ptr\. The memory allocated with 'new \[\]' will be cleaned using 'delete'\. clSocketBase\.cpp:282

```cpp
int clSocketBase::ReadMessage(wxString& message, int timeout)
{
  ....
  size_t message_len(0);
  ....
  message_len = ::atoi(....);
  ....
  std::unique_ptr<char> pBuff(new char[message_len]);
  ....
}
```

The analyzer has detected an issue: the use of smart pointers can cause undefined behavior\. In the code, the _std::unique\_ptr_ class template is instantiated with the _char_ type\. Therefore, a specialization, whose destructor uses the _operator delete_ to release an object, is chosen\. However, an array, allocated using the _operator new\[\]_, is passed to the smart pointer\._ _[Here](https://pvs-studio.com/en/blog/posts/cpp/0973/) you can read why, in C\+\+, arrays should be deleted using the _operator delete\[\]_, and why undefined behavior occurs\.

To fix the error, instantiate the _std::unique\_ptr_ class template with the _char\[\]_ type:

```cpp
std::unique_ptr<char[]> pBuff { new char[message_len] };
```

**Fragment N2**

The analyzer warning: [V762](https://pvs-studio.com/en/docs/warnings/v762/) It is possible a virtual function was overridden incorrectly\. See third argument of function 'Update' in derived class 'clProgressDlg' and base class 'wxGenericProgressDialog'\. progress\_dialog\.h:47, progdlgg\.h:44

The analyzer has detected an incorrect virtual function overriding\. Here's what the function looks like in the base class:

```cpp
class WXDLLIMPEXP_CORE wxGenericProgressDialog : public wxDialog
{
public:
....

    virtual bool Update(int value,
                        const wxString& newmsg = wxEmptyString,
                        bool *skip = NULL);

....
};
```

And here's what the function looks like in the derived class:

```cpp
class clProgressDlg : public wxProgressDialog
{
public:
    ....
    bool Update(int value, const wxString& msg);
    ....
};
```

Since the first two function parameters are the same, we can conclude that the developers wanted to override the virtual function\. However, the default parameters are also a part of the function signature\. Therefore, the _clProgressDlg::Update_ function does not actually override the _wxGenericProgressDialog::Update_ virtual function, but hides it\.

The correct way to declare a virtual function is as follows:

```cpp
class clProgressDlg : public wxProgressDialog
{
public:
    ....
    bool Update(int value, const wxString& msg, bool *skip);
    ....
};
```

Since C\+\+11, it is possible \(and even necessary\) to use the [_override_](https://en.cppreference.com/w/cpp/language/override) specifier to avoid such errors:

```cpp
class clProgressDlg : public wxProgressDialog
{
public:
    ....
    bool Update(int value, const wxString& msg, bool *skip) override;
    ....
};
```

Now the compiler throws an error if the virtual function does not override anything in the base class\. 

Let's take a look at similar warnings:

<details>
   <summary>Spoiler</summary>

* V762 It is possible a virtual function was overridden incorrectly\. See second argument of function 'Pulse' in derived class 'clProgressDlg' and base class 'wxGenericProgressDialog'\. progress\_dialog\.h:48, progdlgg\.h:45
* V762 It is possible a virtual function was overridden incorrectly\. See qualifiers of function 'WantsErrors' in derived class 'DbgVarObjUpdate' and base class 'DbgCmdHandler'\. dbgcmd\.h:504, dbgcmd\.h:59
* V762 It is possible a virtual function was overridden incorrectly\. See first argument of function 'OnURL' in derived class 'ChangeLogPage' and base class 'ChangeLogPageBase'\. changelogpage\.h:51, subversion2\_ui\.h:351
* V762 It is possible a virtual function was overridden incorrectly\. See qualifiers of function 'GetStatusBar' in derived class 'MainFrameBase' and base class 'wxFrameBase'\. gui\.h:161, frame\.h:119
* V762 It is possible a virtual function was overridden incorrectly\. See qualifiers of function 'GetMenuBar' in derived class 'MainFrameBase' and base class 'wxFrameBase'\. gui\.h:162, frame\.h:85
* V762 It is possible a virtual function was overridden incorrectly\. See sixth argument of function 'InsertPage' in derived class 'clGTKNotebook' and base class 'wxNotebook'\. GTKNotebook\.hpp:69, notebook\.h:87
* V762 It is possible a virtual function was overridden incorrectly\. See fifth argument of function 'CreateLinkTargets' in derived class 'BuilderGnuMakeOneStep' and base class 'BuilderGNUMakeClassic'\. builder\_gnumake\_onestep\.h:60, builder\_gnumake\.h:75
* V762 It is possible a virtual function was overridden incorrectly\. See sixth argument of function 'CreateLinkTargets' in derived class 'BuilderGnuMakeOneStep' and base class 'BuilderGNUMakeClassic'\. builder\_gnumake\_onestep\.h:60, builder\_gnumake\.h:75
* V762 It is possible a virtual function was overridden incorrectly\. See first argument of function 'DeleteAllItems' in derived class 'clDataViewListCtrl' and base class 'clTreeCtrl'\. clDataViewListCtrl\.h:147, clTreeCtrl\.h:434


</details>
**Fragment N3**

The analyzer warning: [V595](https://pvs-studio.com/en/docs/warnings/v595/) The 'dbgr' pointer was utilized before it was verified against nullptr\. Check lines: 349, 351\. simpletable\.cpp:349, simpletable\.cpp:351

```cpp
void WatchesTable::OnCreateVariableObject(....)
{
  ....
  if (dbgr->GetDebuggerInformation().defaultHexDisplay == true)
    dbgr->SetVariableObbjectDisplayFormat(DoGetGdbId(item),
                                        DBG_DF_HEXADECIMAL);

  if (dbgr)
    DoRefreshItem(dbgr, item, true);
  ....
}
```

The analyzer has detected the following error: a pointer is dereferenced first, and only then it is checked for _NULL_\.

Let's take a look at similar warnings:

<details>
   <summary>Spoiler</summary>

* V595 The 'win' pointer was utilized before it was verified against nullptr\. Check lines: 1115, 1127\. DiffSideBySidePanel\.cpp:1115, DiffSideBySidePanel\.cpp:1127
* V595 The 'm\_vsb' pointer was utilized before it was verified against nullptr\. Check lines: 212, 224\. clScrolledPanel\.cpp:212, clScrolledPanel\.cpp:224
* V595 The 'ms\_instance' pointer was utilized before it was verified against nullptr\. Check lines: 24, 25\. php\_parser\_thread\.cpp:24, php\_parser\_thread\.cpp:25
* V595 The 'tok' pointer was utilized before it was verified against nullptr\. Check lines: 2070, 2094\. checkmemoryleak\.cpp:2070, checkmemoryleak\.cpp:2094
* V595 The 'parent' pointer was utilized before it was verified against nullptr\. Check lines: 1006, 1008\. checkuninitvar\.cpp:1006, checkuninitvar\.cpp:1008
* V595 The 'tok1' pointer was utilized before it was verified against nullptr\. Check lines: 9368, 9369\. tokenize\.cpp:9368, tokenize\.cpp:9369
* V595 The 'pResult' pointer was utilized before it was verified against nullptr\. Check lines: 522, 526\. SqliteDatabaseLayer\.cpp:522, SqliteDatabaseLayer\.cpp:526


</details>


**Fragment N4**

The analyzer warning: [V766](https://pvs-studio.com/en/docs/warnings/v766/) An item with the same key ''\.'' has already been added\. wxCodeCompletionBoxManager\.cpp:19

```cpp
std::unordered_set<wxChar> delimiters =
  { ':', '@', '.', '!', ' ', '\t', '.', '\\', 
    '+', '*', '-', '<', '>', '[', ']', '(', 
    ')', '{', '}',  '=', '%', '#', '^', '&', 
    '\'', '"', '/', '|',  ',', '~', ';', '`' };
```

Can you see what's wrong here? Because of all the single quotation marks, the eye may not see that the _'\.'_ character has been added again\. It is possible that they forgot to add some other character here, or it's just a random duplicate that can be removed\. 

Another similar fragment: 

* V766 An item with the same key '"MSYS2/GCC"' has already been added\. compiler\.cpp:621, compiler\.cpp:620

**Fragment N5**

The analyzer warning: [V501](https://pvs-studio.com/en/docs/warnings/v501/) There are identical sub\-expressions 'result\.second\.empty\(\)' to the left and to the right of the '\|\|' operator\. RemotyNewWorkspaceDlg\.cpp:19

```cpp
void RemotyNewWorkspaceDlg::OnBrowse(wxCommandEvent& event)
{
  auto result = ::clRemoteFileSelector(_("Seelct a folder"));
  if (result.second.empty() || result.second.empty())
  {
    return;
  }
  ....
}
```

Developers made a typo: there are identical subexpressions to the left and right of the _operator \|\|_\. In addition to the _second_ data member, they should have checked the _first_ data member as well\. Sometimes the analyzer's warning indirectly reveals other anomalies in the code\. For example, an incorrect string literal is passed to the _::clRemoteFileSelector_ function :\)

The fixed code:

```cpp
auto result = ::clRemoteFileSelector(_("Select a folder"));
if (result.first.empty() || result.second.empty())
{
  return;
}
```

The analyzer has detected two more similar fragments:

* V501 There are identical sub\-expressions '\!sshSettings\.IsRemoteUploadEnabled\(\)' to the left and to the right of the '\|\|' operator\. PhpSFTPHandler\.cpp:104
* V501 There are identical sub\-expressions 'output\.Contains\("username for"\)' to the left and to the right of the '\|\|' operator\. git\.cpp:1715

**Fragment N6**

The analyzer warning: [V1043](https://pvs-studio.com/en/docs/warnings/v1043/) A global object variable 'GMON\_FILENAME\_OUT' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. static\.h:41

```cpp
// static.h

#include <wx/string.h>

const wxString GMON_FILENAME_OUT = "gmon.out";
....
```

The analyzer has detected a constant instance declaration of the _wxString_ class in the header file\. According to the C\+\+ standard, constants declared in a namespace have [internal linkage](https://pvs-studio.com/en/blog/terms/6506/#ID0AB1BD61C2)\. Including such a file using _\#include_ will create multiple copies of the object\.

Depending on the C\+\+ standard you use, there are two ways to avoid this behavior\. Starting with C\+\+17, you can declare a variable with the [_inline_](https://en.cppreference.com/w/cpp/language/inline) specifier\. This feature is very useful when you write header\-only libraries\. In versions prior to C\+\+17, you need to declare a variable with the _extern_ specifier in a header file and put its definition in a compiled file: 

```cpp
// Since C++17

// static.h

#include <wx/string.h>

inline const wxString GMON_FILENAME_OUT = "gmon.out";

// -----------------------------------------------------

// Until C++17

// static.h

#include <wx/string.h>

extern const wxString GMON_FILENAME_OUT;

// static.cpp

#include "static.h"

const wxString GMON_FILENAME_OUT = "gmon.out";
```

Let's take a look at similar warnings:

<details>
   <summary>Spoiler</summary>

* V1043 A global object variable 'DOT\_FILENAME\_PNG' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. static\.h:42
* V1043 A global object variable 'snippetSet' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. swGlobals\.h:41
* V1043 A global object variable 's\_plugName' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. scGlobals\.h:37
* V1043 A global object variable 'svnNO\_FILES\_TO\_DISPLAY' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. subversion\_strings\.h:29
* V1043 A global object variable 'CPPCHECK\_DEFAULT\_COMMAND' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. cppchecksettingsdlg\.h:31
* V1043 A global object variable 'CWE119' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. checkbufferoverrun\.h:48
* V1043 A global object variable 'CWE398' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. checkexceptionsafety\.h:37
* V1043 A global object variable 'emptyString' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. config\.h:23
* V1043 A global object variable 'DEFAULT\_AUI\_DROPDOWN\_FUNCTION' is declared in the header\. Multiple copies of it will be created in all translation units that include this header file\. wxc\_widget\.h:27
* \.\.\.\.


</details>
**Fragment N7**

The analyzer warning: [V773](https://pvs-studio.com/en/docs/warnings/v773/) Visibility scope of the 'imageList' pointer was exited without releasing the memory\. A memory leak is possible\. acceltabledlg\.cpp:61, acceltabledlg\.cpp:47

```cpp
AccelTableDlg::AccelTableDlg(wxWindow* parent)
  : AccelTableBaseDlg(parent)
{
  wxImageList* imageList = new wxImageList(16, 16); // <=
  imageList->Add(PluginManager::Get()->
                                GetStdIcons()->
                                LoadBitmap("list-control/16/sort"));
  imageList->Add(PluginManager::Get()->
                                GetStdIcons()->
                                LoadBitmap("list-control/16/sort"));

  clKeyboardManager::Get()->GetAllAccelerators(m_accelMap);
  PopulateTable("");

  CentreOnParent();

  m_textCtrlFilter->SetFocus();

  SetName("AccelTableDlg");
  WindowAttrManager::Load(this);
}
```

The analyzer has detected a possible memory leak\. It looks like the developers forgot to pass the _imageList_ variable somewhere\.

Here are more fragments that look suspicious:

* V773 Visibility scope of the 'pDump' pointer was exited without releasing the memory\. A memory leak is possible\. ErdCommitWizard\.cpp:273, ErdCommitWizard\.cpp:219
* V773 The function was exited without releasing the 'argv' pointer\. A memory leak is possible\. unixprocess\_impl\.cpp:288, unixprocess\_impl\.cpp:286
* V773 The function was exited without releasing the 'child' pointer\. A memory leak is possible\. compilersfoundmodel\.cpp:135, compilersfoundmodel\.cpp:127
* V773 The function was exited without releasing the 'child' pointer\. A memory leak is possible\. xdebuglocalsviewmodel\.cpp:135, xdebuglocalsviewmodel\.cpp:127

**Fragment N8**

The analyzer warning: [V649](https://pvs-studio.com/en/docs/warnings/v649/) There are two 'if' statements with identical conditional expressions\. The first 'if' statement contains function return\. This means that the second 'if' statement is senseless\. Check lines: 372, 375\. clTreeCtrlModel\.cpp:375, clTreeCtrlModel\.cpp:372

```cpp
bool clTreeCtrlModel::GetRange(....) const
{
  items.clear();

  if (from == nullptr || to == nullptr)
  {
    return false;
  }

  if (from == nullptr)
  {
    items.push_back(to);
    return true;
  }

  if (to == nullptr)
  {
    items.push_back(from);
    return true;
  }
  ....
}
```

Take a look at the first _if_\. Control flow goes to the next _if_ only if _from \!\= nullptr && to \!\= nullptr_\. It means that the control flow will not go to any of the following _if_'s\.

In fact, the first check should have looked like this:

```cpp
if (from == nullptr && to == nullptr)
{
  return false;
}
```

The analyzer has detected a similar fragment:

* V649 There are two 'if' statements with identical conditional expressions\. The first 'if' statement contains function return\. This means that the second 'if' statement is senseless\. Check lines: 1998, 2000\. ShapeCanvas\.cpp:2000, ShapeCanvas\.cpp:1998

**Fragment N9**

The analyzer warning: [V668](https://pvs-studio.com/en/docs/warnings/v668/) There is no sense in testing the 'pDump' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. ErdCommitWizard\.cpp:220

```cpp
void BackupPage::OnBtnBackupClick(wxCommandEvent& event)
{
  ....
  DumpClass* pDump = new DumpClass(....);
  if (pDump) dumpResult = pDump->DumpData();
  ....
}
```

In the code above, the value of the pointer returned by the _operator new_ is compared to null\. This operation is pointless\. When the check for null happens, the pointer is always valid\.

If memory cannot be allocated, the _std::bad\_alloc_ exception is thrown\. If exceptions are disabled, _std::abort_ is called\. In any case, the value of the _pDump_ pointer is always non\-null\.

Let's take a look at similar warnings:

<details>
   <summary>Spoiler</summary>

* V668 There is no sense in testing the 'pLabel' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. ErdForeignKey\.cpp:42
* V668 There is no sense in testing the 'pBitmap' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. ErdTable\.cpp:244
* V668 There is no sense in testing the 'm\_pLabel' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. ErdView\.cpp:100
* V668 There is no sense in testing the 'col' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. TableSettings\.cpp:96
* V668 There is no sense in testing the 'pOutFile' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. dumpclass\.cpp:66
* V668 There is no sense in testing the 'm\_proc' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. async\_executable\_cmd\.cpp:182
* V668 There is no sense in testing the 'm\_pEngine' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. spellcheck\.cpp:144
* V668 There is no sense in testing the 'pResultSet' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. SqliteDatabaseLayer\.cpp:199
* V668 There is no sense in testing the 'buffer' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. ShapeDataObject\.cpp:65
* V668 There is no sense in testing the 'node' pointer against null, as the memory was allocated using the 'new' operator\. The exception will be generated in the case of memory allocation error\. XmlSerializer\.cpp:357


</details>
**Fragment N10**

The analyzer warning: [V587](https://pvs-studio.com/en/docs/warnings/v587/) An odd sequence of assignments of this kind: A \= B; B \= A;\. Check lines: 483, 484\. SqlCommandPanel\.cpp:484, SqlCommandPanel\.cpp:483

```cpp
wxArrayString SQLCommandPanel::ParseSql() const
{
  ....
  int startPos = 0;
  int stopPos = 0;
  ....
  startPos = stopPos;
  stopPos = startPos;
  ....  
}
```

The analyzer has detected a suspicious sequence of variable assignments\. Perhaps the developers intended to swap the variables\. Instead, they set them to the same value_\._

**Fragment N11**

The analyzer warning: [V590](https://pvs-studio.com/en/docs/warnings/v590/) Consider inspecting the 'where \!\= std::string::npos && where \=\= 0' expression\. The expression is excessive or contains a misprint\. dbgcmd\.cpp:60

```cpp
void wxGDB_STRIP_QUOATES(wxString& currentToken)
{
  size_t where = currentToken.find(wxT("\""));

  if (where != std::string::npos && where == 0) {
     currentToken.erase(0, 1);
  }
  ....
}
```

If the string begins with the double quotation mark, the code removes it\. According to the standard, _std::string::npos_ always equals to the maximum value represented by the _size\_t_ type\. That is, _std::string::npos_ will never be 0\.

In fact, there is a way to enhance the code:

```cpp
if (!currentToken.empty() && currentToken[0] == wxT('"')) 
{
   currentToken.erase(0, 1);
}
```

Here's another similar warning:

* V590 Consider inspecting the 'where \!\= std::string::npos && where \=\= 0' expression\. The expression is excessive or contains a misprint\. dbgcmd\.cpp:70

**Fragment N12**

The analyzer warning: [V523](https://pvs-studio.com/en/docs/warnings/v523/) The 'then' statement is equivalent to the 'else' statement\. mainbook\.cpp:450, mainbook\.cpp:442

```cpp
void MainBook::GetAllEditors(clEditor::Vec_t& editors, size_t flags)
{
  ....
  if (!(flags & kGetAll_DetachedOnly))
  {
    if (!(flags & kGetAll_RetainOrder))
    {
      // Most of the time we don't care about
      // the order the tabs are stored in
      for (size_t i = 0; i < m_book->GetPageCount(); i++)
      {
        clEditor* editor = dynamic_cast<clEditor*>(m_book->GetPage(i));
        if (editor)
        {
          editors.push_back(editor);
        }
      }
    }
    else
    {
      for (size_t i = 0; i < m_book->GetPageCount(); i++)
      {
        clEditor* editor = dynamic_cast<clEditor*>(m_book->GetPage(i));
        if (editor)
        {
          editors.push_back(editor);
        }
      }
    }
  }
  ....
}
```

The analyzer has detected a fragment where _then_ and _else_ branches of the _if_ statement are completely identical\. Here are eight more similar warnings:

* V523 The 'then' statement is equivalent to the 'else' statement\. art\_metro\.cpp:289, art\_metro\.cpp:287
* V523 The 'then' statement is equivalent to the 'else' statement\. clStatusBar\.cpp:151, clStatusBar\.cpp:147
* V523 The 'then' statement is equivalent to the 'else' statement\. php\_workspace\_view\.cpp:1001, php\_workspace\_view\.cpp:999
* V523 The 'then' statement is equivalent to the 'else' statement\. art\_metro\.cpp:334, art\_metro\.cpp:332
* V523 The 'then' statement is equivalent to the 'else' statement\. symboldatabase\.cpp:1299, symboldatabase\.cpp:1297
* V523 The 'then' statement is equivalent to the 'else' statement\. tokenize\.cpp:10387, tokenize\.cpp:10381
* V523 The 'then' statement is equivalent to the 'else' statement\. parser\.hpp:155, parser\.hpp:151
* V523 The 'then' statement is equivalent to the 'else' statement\. sizer\_flags\_list\_view\.cpp:125, sizer\_flags\_list\_view\.cpp:122

**Fragment N13**

The analyzer warning: [V517](https://pvs-studio.com/en/docs/warnings/v517/) The use of 'if \(A\) \{\.\.\.\} else if \(A\) \{\.\.\.\}' pattern was detected\. There is a probability of logical error presence\. Check lines: 203, 213\. new\_quick\_watch\_dlg\.cpp:203, new\_quick\_watch\_dlg\.cpp:213

```cpp
void DisplayVariableDlg::UpdateValue(....)
{
  ....
  wxTreeItemId item = iter->second;

  if (item.IsOk())
  {
    ....
  }
  else if (item.IsOk())
  {
    ....
  }
  ....
}
```

In the example above, the same _item\.IsOk\(\)_ condition is passed to _if_ and _else if_\. We're dealing with a logical error here\.

Here are two similar warnings:

* V517 The use of 'if \(A\) \{\.\.\.\} else if \(A\) \{\.\.\.\}' pattern was detected\. There is a probability of logical error presence\. Check lines: 53, 55\. symbol\_tree\.cpp:53, symbol\_tree\.cpp:55
* V517 The use of 'if \(A\) \{\.\.\.\} else if \(A\) \{\.\.\.\}' pattern was detected\. There is a probability of logical error presence\. Check lines: 82, 84\. symbol\_tree\.cpp:82, symbol\_tree\.cpp:84

**Fragment N14**

The analyzer warning: [V614](https://pvs-studio.com/en/docs/warnings/v614/) Uninitialized buffer 'buf' used\. Consider checking the first actual argument of the 'Write' function\. wxSerialize\.cpp:1039

```cpp
bool wxSerialize::WriteDouble(wxFloat64 value)
{
  if (CanStore())
  {
    SaveChar(wxSERIALIZE_HDR_DOUBLE);

    wxInt8 buf[10];
    m_odstr.Write(buf, 10);
  }

  return IsOk();
}
```

The analyzer has detected the use of the _buf_ uninitialized variable\. It may cause unpredictable results\.

Let's take a look at similar warnings:

* V614 Potentially uninitialized pointer 'm\_item' used\. wxc\_aui\_tool\_stickiness\.cpp:8
* V614 Potentially uninitialized variable 'err' used\. cppcheck\.cpp:175
* V614 The 'p' smart pointer is utilized immediately after being declared or reset\. It is suspicious that no value was assigned to it\. connection\_impl\.hpp:2200

**Fragment N15**

The analyzer warning: [V728](https://pvs-studio.com/en/docs/warnings/v728/) An excessive check can be simplified\. The '\|\|' operator is surrounded by opposite expressions '\!false' and 'false'\.  clDebuggerBreakpoint\.cpp:26

```cpp
clDebuggerBreakpoint::clDebuggerBreakpoint(const clDebuggerBreakpoint& BI)
{
  ....
  if (!is_windows || (is_windows && !file.Contains("/"))) 
  {
    ....
  }
  ....
}
```

The analyzer has detected code that can be simplified\. Opposite expressions are to the left and right of the _operator \|\|_\. The code is redundant — we can simplify it by reducing the number of checks: 

```cpp
if (!is_windows || !file.Contains("/"))
{
  ....
}
```

The analyzer has detected 17 similar fragments, take a look at some of them:

* V728 An excessive check can be simplified\. The '\|\|' operator is surrounded by opposite expressions '\!matcher' and 'matcher'\.  ssh\_account\_info\.cpp:108
* V728 An excessive check can be simplified\. The '\(A && \!B\) \|\| \(\!A && B\)' expression is equivalent to the 'bool\(A\) \!\= bool\(B\)' expression\. assignedfilesmodel\.cpp:310
* V728 An excessive check can be simplified\. The '\|\|' operator is surrounded by opposite expressions 'data\-\>m\_wxcWidget\-\>IsSizer\(\)' and '\!data\-\>m\_wxcWidget\-\>IsSizer\(\)'\.  wxguicraft\_main\_view\.cpp:530

## Conclusion

In conclusion, I would like to point out that this article is my first attempt to analyze code using PVS\-Studio\. I have gained valuable experience in the field of static code analysis\. The bugs found in the CodeLite project showed me the importance of such analysis\. Based on the analysis results, the project authors can further develop and enhance the code to provide users with an IDE of higher quality\.

Following the tradition, let me end the article by offering you to [try out](https://pvs-studio.com/en/pvs-studio/try-free/) the PVS\-Studio analyzer\. We also [provide](https://pvs-studio.com/en/order/open-source-license/) a free license for open\-source projects\.