This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 6.2.2 - All declarations [1] of a variable or function shall have the same type
[basic.def.odr] NDR 2; Undefined 5
[dcl.link]
[over.load] / 2.1
[dcl.attr.noreturn] NDR 1
Category: Required
Analysis: Decidable,System
Amplification
Two variable declarations [1] with the same name refer to the same variable if they have the same scope. Two function
declarations [1] with the same name refer to the same function if they have the same scope and have equivalent parameter declarations (see
[over.dcl]/1). Declarations [1] of variables in the global scope and declarations [1] of variables and functions with C linkage that
have the same identifier declare a single entity (note there is no overloading in C).
For the purposes of this rule:
- An array declared with an unknown bound has the same type as an array declared with the same element type and a known bound; and
- A pointer to an incomplete type has the same type as a pointer to the complete type.
The following restrictions apply:
- When several declarations [1] of the same entity exist, they shall have the same type;
- All declarations [1] of a function declared with the
[[noreturn]] attribute shall have that attribute (see
[dcl.attr.noreturn]).
Note: functions with C linkage are always distinct from functions with C++ linkage.
Rationale
It is undefined behaviour if the declarations [1] of a variable or function in two different translation units do not
have the same type.
While attributes are not part of a function type, inconsistent use of the [[noreturn]] attribute results in an ill-formed (no
diagnostic required) program.
Example
All the declarations [1] of f3 in the following files conflict with each other and are non-compliant.
// File a.cpp
typedef int32_t myint;
extern int32_t a; // Non-compliant - see b.cpp
extern int32_t b []; // Compliant
extern char c; // Non-compliant - see b.cpp
extern int32_t d; // Compliant
extern myint e; // Compliant
int32_t f1(); // Non-compliant - see b.cpp
int32_t f2( int32_t ); // Compliant
extern "C" int32_t f3( int32_t ); // Non-compliant
int32_t f4(); // Non-compliant - see b.cpp
// File b.cpp
extern int64_t a; // Non-compliant - see a.cpp
extern int32_t b [ 5 ]; // Compliant
int16_t c; // Non-compliant - see a.cpp
int32_t d { 1 }; // Compliant
int32_t e; // Compliant
char f1(); // Non-compliant - see a.cpp
char f2( char ); // Compliant - not the same function as
// int32_t f2( int32_t )
extern "C" int32_t f3( char ); // Non-compliant
int32_t f4() noexcept; // Non-compliant - see a.cpp
// Different exception specification
// File c.cpp
extern "C" int32_t f3; // Non-compliant
// File d.cpp
int32_t f3; // Non-compliant
Glossary
[1] Declaration
A declaration introduces the name of an entity into a translation unit (see [basic.def]/1).
An entity may be declared several times. The first declaration of an entity in a translation unit is
called an introduction [2]. All subsequent declarations are called redeclarations [3].
A definition [4] is a declaration, as described in [basic.def]/2.
[2] Introduction
See declaration [1].
[3] Redeclaration
See declaration [1].
[4] Definition
See declaration [1].
Copyright The MISRA Consortium Limited © 2023