Main Content

CERT C: Rec. DCL07-C

Include the appropriate type information in function declarators

Description

Rule Definition

Include the appropriate type information in function declarators.1

Polyspace Implementation

The rule checker checks for these issues:

  • Cast between function pointers with different types.

  • Function declared implicitly.

Examples

expand all

Issue

The issues occurs when you perform a conversion between a pointer to a function and any other type.

Polyspace® considers both explicit and implicit casts when checking this rule. However, casts from NULL or (void*)0 do not violate this rule.

Risk

The rule forbids the following two conversions:

  • Conversion from a function pointer to any other type. This conversion causes undefined behavior.

  • Conversion from a function pointer to another function pointer, if the function pointers have different argument and return types.

    The conversion is forbidden because calling a function through a pointer with incompatible type results in undefined behavior.

Example - Cast between two function pointers
typedef void (*fp16) (short n);
typedef void (*fp32) (int n);

#include <stdlib.h>                     /* To obtain macro  NULL */

void func(void) {   /* Exception 1 - Can convert a null pointer 
                     * constant into a pointer to a function */
  fp16 fp1 = NULL;                 /* Compliant - exception  */
  fp16 fp2 = (fp16) fp1;           /* Compliant */
  fp32 fp3 = (fp32) fp1;           /* Non-compliant */
  if (fp2 != NULL) {}              /* Compliant - exception  */
  fp16 fp4 = (fp16) 0x8000;        /* Non-compliant - integer to 
                                    * function pointer */}

In this example, the rule is violated when:

  • The pointer fp1 of type fp16 is cast to type fp32. The function pointer types fp16 and fp32 have different argument types.

  • An integer is cast to type fp16.

The rule is not violated when function pointers fp1 and fp2 are cast to NULL.

Issue

The issue occurs when you declare a function implicitly.

Risk

An implicit declaration occurs when you call a function before declaring or defining it. When you declare a function explicitly before calling it, the compiler can match the argument and return types with the parameter types in the declaration. If an implicit declaration occurs, the compiler makes assumptions about the argument and return types. For instance, it assumes a return type of int. The assumptions might not agree with what you expect and cause undesired type conversions.

Example - Function Not Declared Before Call
#include <math.h>

extern double power3 (double val, int exponent);
int getChoice(void);

double func() {
    double res;
    int ch = getChoice();
    if(ch == 0) {
        res = power(2.0, 10);    /* Non-compliant */
    }
    else if( ch==1) {
        res = power2(2.0, 10);   /* Non-compliant */
    }
    else {
        res = power3(2.0, 10);   /* Compliant */
        return res;
    }
}

double power2 (double val, int exponent) {
    return (pow(val, exponent));
}

In this example, the rule is violated when a function that is not declared is called in the code. Even if a function definition exists later in the code, the rule violation occurs.

The rule is not violated when the function is declared before it is called in the code. If the function definition exists in another file and is available only during the link phase, you can declare the function in one of the following ways:

  • Declare the function with the extern keyword in the current file.

  • Declare the function in a header file and include the header file in the current file.

Check Information

Group: Rec. 02. Declarations and Initialization (DCL)

Version History

Introduced in R2019a


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.