主要内容

CERT C:Rule DCL31-C

Declare identifiers before using them

描述

规则定义

Declare identifiers before using them.1

Polyspace 实现

规则检查项会检查以下问题:

  • 未显式指定的类型

  • 隐式函数声明

每次使用不合规的标识符时,都会报告此违规。

示例

全部展开

问题

规则检查项会标记未显式指定函数参数或返回类型的情况。要启用对此规则的检查,请为 C 标准版本 (-c-version) 选项使用 c90 值。

风险

在一些情况下,您可以省略 C90 标准中的类型。在这些情况下,会隐式指定 int 类型。然而,省略显式类型可能会让人感到困惑。例如,在声明 extern void foo (char c, const k); 中,k 的类型是 const int,但您期望的可能是 const char

您可以在以下声明中使用隐式类型:

  • 对象声明

  • 参数声明

  • 成员声明

  • typedef 声明

  • 函数返回类型

示例 - 隐式类型
static foo(int a);  /* Non compliant */
static void bar(void);      /* Compliant */

在此示例中,因为 foo 的返回类型是隐式的,所以违反了规则。

问题

当您在声明或定义函数之前调用它时,会出现此问题。

风险

如果在声明或定义函数之前调用函数,会发生隐式声明。如果在调用函数之前显式声明函数,编译器可以将参量和返回类型与声明中的参数类型进行匹配。如果发生隐式声明,编译器会对参量和返回类型进行假设。例如,它会假定返回类型为 int。这些假设可能与预期不符,并导致不期望的类型转换。

示例 - 调用前未声明的函数
#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));
}

在此示例中,当代码中调用未声明的函数时,便违反了此规则。即使代码的后面部分存在函数定义,也会出现违规。

如果在代码中调用某个函数之前已声明该函数,则不会违反此规则。如果函数定义存在于另一个文件中,且仅在链接阶段可用,则可以通过以下方式之一声明该函数:

  • 在当前文件中使用 extern 关键字声明函数。

  • 在头文件中声明函数,然后在当前文件中包含此头文件。

检查信息

组:Rule 02. 声明和初始化 (DCL)

版本历史记录

在 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.