Main Content

Partially duplicated code

A section of code is duplicated in other places with very minor changes

Since R2023a

Description

This defect occurs when a block of code is duplicated in multiple places with only slight changes.

The defect checker does not flag certain blocks as duplicates. For instance, the blocks of code considered almost duplicates have to typically consist of more than a certain number of lines. See also Duplicate Code Detection in Polyspace Bug Finder.

Sometimes, two blocks might appear as exact duplicates, but might be reported as partial duplicates because some of the variables in the duplicate sections have different data types. The event list below the result points to the lines containing such variables.

Risk

Sections of code that do almost the same operations might require unnecessary additional maintenance. Duplicated code also increases the chances you will update the code in one place but forget to update the other. See also Duplicated code and Possible copy-paste error.

Fix

Try to refactor the sections of code to reduce the duplication. For instance, identify parts of the code blocks that are duplicates of each other and refactor them into a dedicated function. You can then replace the duplicated code with calls to the dedicated function.

Examples

expand all

In this example, the two code blocks in the functions updatePinOne() and updatePinTwo() are partial duplicates of each other. The duplicate section of each block copies one structure currentBoard to another structure backupBoard field by field. The only difference is that a different member of the structure currentBoard is updated in each function.

The code duplication can make maintenance difficult. For instance, if the structure type board is updated with more fields, it can be easy to forget copying the new fields in one of the duplicate sections. This omission can lead to a partial structure copy.

typedef struct {
    int pin1;
    int pin2;
    int pin3;
    int pin4;
    int pin5;
    int pin6;
    int pin7;
    int pin8;
} board;

board currentBoard;
board backupBoard;

void updatePinOne(int newVal1) {
     backupBoard.pin1 = currentBoard.pin1; //Beginning of duplicate section #1
     currentBoard.pin1 = newVal1;  
     backupBoard.pin2 = currentBoard.pin2;
     backupBoard.pin3 = currentBoard.pin3;
     backupBoard.pin4 = currentBoard.pin4;
     backupBoard.pin5 = currentBoard.pin5;
     backupBoard.pin6 = currentBoard.pin6;
     backupBoard.pin7 = currentBoard.pin7;
     backupBoard.pin8 = currentBoard.pin8; //End of duplicate section #1
}

void updatePinTwo(int newVal2) {
     backupBoard.pin1 = currentBoard.pin1; //Beginning of duplicate section #2
     currentBoard.pin2 = newVal2; 
     backupBoard.pin2 = currentBoard.pin2;
     backupBoard.pin3 = currentBoard.pin3;
     backupBoard.pin4 = currentBoard.pin4;
     backupBoard.pin5 = currentBoard.pin5;
     backupBoard.pin6 = currentBoard.pin6;
     backupBoard.pin7 = currentBoard.pin7;
     backupBoard.pin8 = currentBoard.pin8; //End of duplicate section #2
}

The event list on the Result Details pane shows:

  • The beginning and end of each duplicate block of code.

  • The line where each block differs from the other.

    If two blocks are exactly identical except for the name of one variable and if the variable is used in multiple places, the event list shows only the first usage of the variable.

Click on an event to navigate to the corresponding location in the source code.

Event list shows beginning and end of each duplicate section

In the Polyspace® user interface, you can see the duplicated code blocks side by side on the Source pane. See Navigate in Separate Window.

Correction – Refactor Code to Avoid Duplication

You can refactor the duplicate sections of code into a common function and replace the sections with calls to this function. In this example, the duplicate sections of the two blocks have been refactored into the backupCurrentBoard() function.

typedef struct {
    int pin1;
    int pin2;
    int pin3;
    int pin4;
    int pin5;
    int pin6;
    int pin7;
    int pin8;
} board;

board currentBoard;
board backupBoard;

void backupCurrentBoard(void) {
     backupBoard.pin1 = currentBoard.pin1; 
     backupBoard.pin2 = currentBoard.pin2;
     backupBoard.pin3 = currentBoard.pin3;
     backupBoard.pin4 = currentBoard.pin4;
     backupBoard.pin5 = currentBoard.pin5;
     backupBoard.pin6 = currentBoard.pin6;
     backupBoard.pin7 = currentBoard.pin7;
     backupBoard.pin8 = currentBoard.pin8;      
}

void updatePinOne(int newVal1) {
    backupCurrentBoard();  
    currentBoard.pin1 = newVal1;         
}

void updatePinTwo(int newVal2) {
    backupCurrentBoard();  
    currentBoard.pin2 = newVal2; 
}

Result Information

Group: Good practice
Language: C | C++
Default: Off
Command-Line Syntax: ALMOST_DUPLICATED_CODE
Impact: Low

Version History

Introduced in R2023a

expand all