Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

Klocwork Refactoring

Klocwork Refactoring

Refactoring is the process of simplifying and clarifying code without changing the program's behavior; the beginning and end products are functionally identical. Refactoring makes code:

  • easier to maintain and re-use
  • simpler to understand
  • cheaper to change

Using Klocwork Refactoring in your coding environment

For most of the refactoring options, you first need to select some code to refactor. Then right-click, select the Klocwork menu, and choose the appropriate refactoring option. You can also use keyboard shortcuts. For shortcuts, see:

For Vim, the plug-in is not installed automatically with the Klocwork Desktop Analysis package. To configure it, see:

Available refactorings

You can:

  • rename entities whose scope is file-local, in order to make your identifier names more meaningful.
  • extract methods or functions (with duplicate detection in Eclipse and Visual Studio) from large and unwieldy methods to create smaller and more logical functions. The newly extracted function is added to your source file, while the selected code is replaced with a call to that function.
  • introduce variables (with duplicate detection in Eclipse and Visual Studio) to simplify complicated expressions. Occurrences of the expression are replaced with the new variable(s).
  • inline variables, replacing all occurrences of a given variable with its initial value; this is the opposite of introducing variables.
  • inline functions to remove the overhead of an overly segmented source layout. Typical candidates for inlining are simple functions that are called from few locations, but which might be invoked frequently at runtime, such as from an inner loop. These are functions that might best benefit from the overhead of function calling being removed. Inlining functions involves placing the method's body into the body of its caller(s) and removing the method.
  • analyze headers, reporting missing transitive includes and unnecessary includes.
  • optimize headers, applying any unused header and missing transitive header changes all in one step, without user confirmation.

Rename

To make identifier names more meaningful, rename a variable or function. Watch a demo. You can rename:

  • local variables
  • function parameters
  • static functions and variables

The new name is checked against existing code to prevent hiding names of existing variables, functions, types, or namespaces, as well as naming conflicts.

Example

int boo(int b) { 
}
int bar(int (*func)(char*)) { 		 
    return 1; 
} 
void foo(int a) { 
    int i = 2;
    i = 3;
    a = 567;
    a = boo(a); 
}

In the above snippet, b, func, a and i can all be renamed as specified.

Extract Function

When you use the Extract Function option, a new function is created, and the selected code is inserted as the body of the function. The selected code must be a syntactically complete, non-empty sequence of complete statements and/or expressions.

Implementation notes

  • The selected code fragment is replaced with a call to a new function, and any variables that are used inside the code fragment are passed to a new function as input or output parameters.
  • A new function with only one output parameter of a primitive type (such as pointer, char, bool, or int) is automatically converted into a function, returning a value of this type and no output parameters.
  • For C output, parameters are declared as pointers to the original type.
  • For C++ output, parameters are declared as references to the original type. If the current function is a member function of a C++ class, a declaration of the new function is inserted into the class definition as a protected member.
  • The original indentation and whitespace are preserved where possible
  • Comments, macros and preprocessor directives within your selection are preserved during this code transformation. This example code shows some code selected for refactoring:
int foo() {
  int a;
  /* selection starts -> */
  #define MY_MACRO 1
  a = MY_MACRO;
  /*<- selection ends*/
  a = a + 20;
  return a;
}

You can see that the 'define' directive is preserved in the extracted function:

int extracted_function()
{
  int a;
  #define MY_MACRO 1
  a = MY_MACRO;
  return a;
}

Limitations

  • The selected code fragment can't contain jump statements ("goto"), but return statements will work.
  • The selected code fragment can't contain label statements, but switch statements (with labels) will work.
  • Extraction from template functions is not supported.

Example

int main() {		 
 int a;			       
   a++ ;			
  return a;
}

Here, 'a++' can be extracted into 'new_function'.

Result

 void new_function(int *a) {  
  (*a)++ ; 
}
int main() { 
 int a; 
 new_function(&a) ; 
 return a; 
}


Introduce Variable

Introduce Variable allows you to quickly create a new local variable from the selected expression, initialize it with the expression, and replace all occurrences of the expression in the code with references to the newly introduced variable. The opposite action is to refactor by inlining a variable, which replaces the variable with its initial expression.

Implementation notes

  • The declaration of the new local variable, initialized with the selected expression, is inserted into the current statement. The selected expression is replaced with the name of the new variable.
  • The new name is checked against existing code to prevent hiding names of existing variables, functions, types, or namespaces, as well as naming conflicts.
  • For C++, the declaration and initializer of the new variable are merged into a single statement and inserted directly before the selected statement.
  • For C, the declaration and initializer may have to be split. The declaration is inserted at the beginning of the current block or function, and the initializing assignment is inserted directly before the selected statement.

Example

The bold text in the snippet below can be replaced with a variable:

int main() { 				
    int c; 				     
    c = 1 +  2 + 3 + 4 + 5 ;		     
    return c; 				      
}

Result

int main() { 
  int temp ; 
 int c;
  temp = 2 + 3 + 4 + 5 ; 
 c = 1 +  temp ;				     				  
 return c; 
}

Inline Variable

Inline Variable allows you to replace all occurrences of a given variable with its initial value. The opposite action is to refactor by introducing a variable.

Example

The bold variable can be replaced by an expression:

int main() { 
  int temp ; 
 int c;
  temp  = 2 + 3 + 4 + 5; 
 c = 1 +  temp ;				     				  
 return c; 
}

Result

int main() { 				
    int c; 				     
    c = 1 +  2 + 3 + 4 + 5 ;		     
    return c; 				      
}

Inline Function

When you inline a function, the complete body of a function is inserted for each occurrence of the selected function.

Watch a demo of this feature here.

Implementation notes

  • When you select the definition of a function, the function is removed from the source file, and every call to this function is replaced with the function body.
  • When you select a call to a function, only this call is inlined, and the function definition is left unchanged.
  • The parameters and local variables of a function are renamed during substitution.

Limitations

  • Only inline and static functions are supported.
  • You can't inline:
    • recursive functions
    • functions with more than one return statement
    • functions referenced by address

Example

static int foo(int a) {			  
    int b = a + 2;				    
    return b;				      
}						  
int main() {				      
    int c;					     
    c =  foo(1) ;				 
    return c; 
} 

In this example, we can inline 'foo'.

Result

int main() { 
 int c;
  int a = 1;  
  int b = a + 2;  
  c = b; 
 return c;
}

Can't inline function declared in system header

You'll see this message if the function definition is found in the system header.

For example, this message will occur if there's an attempt to inline 'pow' from 'math.h' in the snippet below:

#include <iostream>
 #include <stdio.h>
 #include <math.h>
 
 using namespace std;
 
 #define PI 3.14
 
 static float getArea(float radius) {
   float area = PI * *pow(radius, 2)*;
   return area;
 }

Can't inline function: This function is invoked using its fully qualified name

You can inline a function if it is called directly from another class member, but you'll trigger this message if you attempt to inline functions such as 'x->foo()' or 'x.foo()' in the situations noted below:

 class A{
    void foo() {...}
    void abc();
 }
 void A::abc()
 {
    foo(); //we can inline this
 
    A::foo(); //we can't inline this
    A x = new A();
    x->foo(); //we can't inline this
 }

Header Analysis

Watch a demo of Analyze and Optimize Headers here.

Header Analysis allows you to fix problems with the include structure of your code, which can add to compile time and make the system difficult to maintain.

These problems can be solved with these two Klocwork refactorings:

Analyze Headers

Analyze Headers identifies unnecessary or missing transitive includes and presents a refactoring suggestion.

The functionality of this refactoring option is dependent on your choice of IDE.

Analyze Headers is not available in Vim.

Optimize Headers

Use the Optimize Headers refactoring option to find and refactor unnecessary or missing includes in one step, without prompting from you. This is in slight contrast to Analyze Headers, which notifies you of unnecessary or missing transitive includes and presents you with the refactoring suggestion that you can implement or not.

For both Visual Studio and Eclipse, right-click anywhere in your current file and select Klocwork > Optimize Headers. (You don't need to select any code to optimize headers.)

Header analysis in Visual Studio

Header Analysis allows you to fix problems with the include structure of your code, which can add to compile time and make the system difficult to maintain.

In Visual Studio, unnecessary or missing transitive includes are reported in the issue list as one of the following issues: HA.DUPLICATE, HA.OPTIMIZE or HA.UNUSED.

Note: There are no markers for header analysis issues.

  1. To solve a Header Analysis issue manually, double-click on the issue found in the issues list. This will bring you to the line of code containing the issue.
  2. Right-click the issue marker and a pop-up menu will appear with the following possible actions:

Once you make a change, the issue will disappear from the issue list.

If you prefer to make these changes automatically, you can right click anywhere in your current file and select Klocwork > Optimize headers. This will automatically fix all header issues within the current file.

To prevent these issues from appearing in the issue list see, disable the Header Analysis checkers.

Removing unused functions in Visual Studio

If you are using one of the Visual Studio plug-ins, you can quickly refactor your code to remove unused functions.

A defined but unused function can lead to development confusion, such as the wrong function with a similar name being called. On rare occasions, the unused function can also find its way into the final executable, which can lead to other vulnerabilities. Klocwork provides two checkers that identify unused functions:

  1. To fix one of these issues, right-click the issue marker on the left margin of the editor and choose one of the following actions:
  2. For UNUSED.FUNC.GEN, choose Remove unused function.

Refactoring shortcuts in Visual Studio

Klocwork Refactoring options can be accessed with the following shortcuts:

Refactoring Shortcut
Extract Function Alt+r, e
Inline Function Alt+r, f
Inline Variable Alt+r,i
Introduce Variable Alt+r, v
Optimize Headers Alt+r,o
Rename Alt+r, r

Header analysis in Eclipse

In Eclipse, you can fix header issues by using the Analyze Headers and Optimize Headers refactoring options by right-clicking anywhere in your current file and selecting Klocwork > Analyze Headers or Optimize Headers.

The Analyze Headers and Optimize Headers menu options are controlled by the Header Analysis checkers. If you disable these checkers, the header analysis refactoring will not be available.

When you use the Analyze Headers refactoring option, unnecessary or missing transitive includes are identified in the current file with a marker that activates a Quick Fix pop-up that provides a refactoring suggestion.

  1. Right-click anywhere in your current file and select Klocwork > Analyze Headers. (You don't have to select any code to analyze your headers).
  2. Click the bug marker or just scroll to your header files to see the Quick Fix icon: .
  3. Click or use <Ctrl+1> to activate the Quick Fix pop-up.
  4. Click the pop-up to proceed with the refactoring.

When you use the Optimize Headers refactoring option, all of the fixes are done for you without the need to go through and fix each individual marker in the file.

Refactoring shortcuts in Eclipse

Klocwork Refactoring options can be accessed with the following shortcuts:

Refactoring Shortcut
Analyze Headers Alt+Shift+K, A
Extract Function Alt+Shift+K, E
Inline Function Alt+Shift+K, I
Inline Variable Alt+Shift+K, N
Introduce Variable Alt+Shift+K, V
Optimize Headers Alt+Shift+K, O
Rename Alt+Shift+K, R