Klocwork RefactoringKlocwork RefactoringRefactoring 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:
Using Klocwork Refactoring in your coding environmentFor 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 refactoringsYou can:
RenameTo make identifier names more meaningful, rename a variable or function. Watch a demo. You can rename:
The new name is checked against existing code to prevent hiding names of existing variables, functions, types, or namespaces, as well as naming conflicts. Exampleint 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 FunctionWhen 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
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
Exampleint 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 VariableIntroduce 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
ExampleThe 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 VariableInline 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. ExampleThe 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 FunctionWhen 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
Limitations
Examplestatic 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 headerYou'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 nameYou 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 AnalysisWatch 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 HeadersAnalyze 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 HeadersUse 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 StudioHeader 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.
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 StudioIf 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:
Refactoring shortcuts in Visual StudioKlocwork Refactoring options can be accessed with the following shortcuts:
Header analysis in EclipseIn 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.
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 EclipseKlocwork Refactoring options can be accessed with the following shortcuts:
|