Main Content

CERT C: Rule DCL40-C

Do not create incompatible declarations of the same function or object

Description

Rule Definition

Do not create incompatible declarations of the same function or object.1

Polyspace Implementation

The rule checker checks for Declaration mismatch.

Examples

expand all

Issue

Declaration mismatch occurs when a function or variable declaration does not match other instances of the function or variable.

Risk

When a mismatch occurs between two variable declarations in different compilation units, a typical linker follows an algorithm to pick one declaration for the variable. If you expect a variable declaration that is different from the one chosen by the linker, you can see unexpected results when the variable is used.

A similar issue can occur with mismatch in function declarations.

Fix

The fix depends on the type of declaration mismatch. If both declarations indeed refer to the same object, use the same declaration. If the declarations refer to different objects, change the names of the one of the variables. If you change a variable name, remember to make the change in all places that use the variable.

Sometimes, declaration mismatches can occur because the declarations are affected by previous preprocessing directives. For instance, a declaration occurs in a macro, and the macro is defined on one inclusion path but undefined in another. These declaration mismatches can be tricky to debug. Identify the divergence between the two inclusion paths and fix the conflicting macro definitions.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example - Inconsistent Declarations in Two Files

file1.c

int foo(void) { //Noncompliant
    return 1;
}

file2.c

double foo(void);

int bar(void) {
    return (int)foo();
}

In this example, file1.c declares foo() as returning an integer. In file2.c, foo() is declared as returning a double. This difference might cause a compilation failure. Polyspace raises a defect on the second instance of foo in file2.

Correction — Align the Function Return Values

One possible correction is to change the function declarations so that they match. In this example, by changing the declaration of foo in file2.c to match file1.c, the defect is fixed.

file1.c

int foo(void) {
    return 1;
}

file2.c

int foo(void);

int bar(void) {
    return foo();
}
Example - Inconsistent Structure Alignment

test1.c

#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

test2.c

#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square; //Noncompliant

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square; 

In this example, a declaration mismatch defect is raised on square in square.h because Polyspace infers that square in square.h does not have the same alignment as square in test2.c. This error occurs because the #pragma pack(1) statement in circle.h declares specific alignment. In test2.c, circle.h is included before square.h. Therefore, the #pragma pack(1) statement from circle.h is not reset to the default alignment after the aCircle structure. Because of this omission, test2.c infers that the aSquare square structure also has an alignment of 1 byte. This defect might cause a compilation failure.

Correction — Close Packing Statements

One possible correction is to reset the structure alignment after the aCircle struct declaration. For the GNU® or Microsoft® Visual compilers, fix the defect by adding a #pragma pack() statement at the end of circle.h.

test1.c

#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

test2.c

#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

#pragma pack()

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square;

Other compilers require different #pragma pack syntax. For your syntax, see the documentation for your compiler.

Correction — Use the Ignore pragma pack directives Option

One possible correction is to add the Ignore pragma pack directives option to your Bug Finder analysis. If you want the structure alignment to change for each structure, and you do not want to see this Declaration mismatch defect, use this correction.

  1. On the Configuration pane, select the Advanced Settings pane.

  2. In the Other box, enter -ignore-pragma-pack.

  3. Rerun your analysis.

    The Declaration mismatch defect is resolved.

Check Information

Group: Rule 02. Declarations and Initialization (DCL)

Version History

Introduced in R2019a

expand all


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.