主要内容

MISRA C++:2023 Rule 6.2.1

The one-definition rule shall not be violated

自 R2024b 起

描述

The one-definition rule shall not be violated. 1

理由

违反一个定义规则 (ODR) 会导致未定义行为。当您代码中的实体出现以下情况时,即违反了 ODR:

  • 没有定义。

  • 在不同的源文件中存在多个非内联定义。

  • 在不同的源文件中存在多个不同的内联定义。

  • 具有不同的初始化值。

Polyspace 实现

在出现以下情况时,规则检查项会报告违规:

  • 同一个函数或对象有多个定义且这些定义中的某些标记不同。

  • 一个内联函数在不同的源文件中有不同的实现。

检查项不会对未使用的代码进行标记,例如:

  • 未实例化的模板

  • 未调用的 staticextern 函数

  • 未调用和未定义的局部函数

  • 未使用的类型和变量

故障排除

如果您预期会出现违规,而 Polyspace® 未报告该违规,请参阅诊断为何编码规范违规未按预期显示

示例

全部展开

此示例使用两个文件:

  • file1.cpp:

    
    typedef struct S //Noncompliant
    {
       int x;
       int y;
    }S; 
    void foo(S& s){
    //...
    } 
  • file2.cpp:

    
    typedef struct S 
    {
       int y;
       int x;
    }S ; 
    void bar(S& s){
    //...
    }

在此示例中,file1.cppfile2.cpp 都定义了结构体 S。不过,这两个定义交换了结构体字段的顺序。

此示例使用三个头文件和两个源文件:

头文件源文件

  • File1.h:

    void  foo(int32_t i);

  • File2.h:

    void  foo(int64_t i);

  • File3.h:

    inline void bar(int64_t i){
    foo(i);
    }

  • File1.cpp:

    #include<cstdint>
    #include "File1.h"
    #include "File3.h"
    void f1(){
    
    bar(23);
    }
    

  • File2.cpp:

    #include<cstdint>
    #include "File2.h"
    #include "File3.h"
    void f2(){
    
    bar(23);
    }
    

File1.cpp 中,内联函数 bar() 包含对 foo(int32_t i) 的调用,但在 File2.cpp 中,函数 bar() 包含对 foo(int64_t i) 的调用。同一内联函数在不同翻译单元中的定义不同,导致违反了此规则。

检查信息

组:基本概念
类别:必需

版本历史记录

在 R2024b 中推出


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.