Main Content

AUTOSAR C++14 Rule A8-4-14

Interfaces shall be precisely and strongly typed

Description

Rule Definition

Interfaces shall be precisely and strongly typed.

Rationale

Interfaces describe the behavior or capabilities of an object. Precisely and strongly typed interfaces specify the purpose and properties of their parameters by using parameters that are custom objects and templates instead of fundamental types. Compare the interfaces in this code snippet:

void draw_circle(float R, float x, float y);
void draw_circle(Length R, Position O);
Both interfaces represent a function that draws a circle. The first interface uses three floating numbers as input parameters. The second interface uses an object of class Length and another object of class Position as input parameters.

  • The second interface makes it explicit that the first parameter is a length and the second parameter is a position. This interface is easy to understand and use because it highlights the required input parameters and their order for a specific circle. By contrast, you cannot discern the input parameters or their order in the first interface because it is not clear how the three floating numbers relate to the circle.

  • The compiler checks the arguments against the input parameter types at compile time. If you put the input parameters of the second interface in the wrong order accidentally, the compiler flags the mismatched parameters at compile time. If all three input parameters of the first interface are floating-point numbers, the compiler cannot check if the input order is correct.

  • The definition of the classes Length and Position can specify the units of these parameters, such as cm or mm. The class definitions can also specify whether these parameters are immutable. When you use fundamental types as input parameters, such specification is difficult.

The first interface is ambiguous because it uses fundamental type input parameters, which can lead to mistakes. Avoid using interfaces that have many fundamental type parameters. Use precisely and strongly typed interfaces instead. Compilers can often optimize such interfaces better than weakly typed interfaces.

When several parameters are related, combine them into a user-defined type. When implementing polymorphic interfaces, use pointers to a common base class instead of pointers to void (void*). For generic interfaces, use templates as parameters.

Polyspace Implementation

In Polyspace®, these types are fundamental types:

  • Integer types, such as int, short, and long

  • Floating point types, such as float or double

  • Boolean (bool) types

  • Pointers to void (void*)

  • Pointers or references to the preceding types

  • typedef of the preceding types

  • Arrays of the preceding types

In Polyspace, enumerations or enums are not fundamental types. Polyspace flags an interface if its input parameters include any of the following:

  • One or more void related types

  • Two or more bool related types

  • Three or more identical fundamental types

You can use alternatives such as comments or parameter names to clarify an interface definition. In such cases, you can justify the Polyspace result by using comments in your result or code. See Address Results in Polyspace User Interface Through Bug Fixes or Justifications

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

Polyspace flags interfaces when their input parameters include:

  • Two or more bool related types

  • Three or more identical fundamental types

Consider the interfaces in this code:

#include <cstdint>
#include <chrono>

void Sleep(std::uint32_t duration);//Compliant

void SetProperty(bool Status);//Compliant

void SetAlarm(std::uint32_t year, std::uint32_t month, //Noncompliant
              std::uint32_t day, std::uint32_t hour,
              std::uint32_t minute, std::uint32_t second);

//Compliant
void StartClock(std::chrono::system_clock::time_point const& when);
typedef struct {
    int a, b, c, d;
} Point;
void Triangle(float a, float b, float c);//Noncompliant
void Rectangle(Point a, Point b, Point c, Point d); //Compliant

main()
{
    //...
}

  • Polyspace flags the interfaces that use three or more fundamental type variables as input parameters, such as SetAlarm() and Triangle().

  • The interfaces StartClock() and Rectangle() use precise and strongly typed input parameters. Polyspace does not flag these interfaces.

  • Polyspace does not flag an interface that has less than three fundamental type input parameters or less than two bool type input parameters.

Polyspace flags interfaces when their input parameters include one or more pointers to void (void*). Consider the interfaces in this code:

#include <cstdint>

class A{
	//...
};
class B:public A{
	//...
};
class C:public A{
	//...
};

void polymorphic_function(void*);//Noncompliant
void polymorphic_function(A*);//Compliant

void printArray(void* Array);//Noncompliant
template <typename T>
void printArray (T* Array);//Compliant

main(){
	//...
}

All pointer types implicitly convert to void*, which is a weak and under-qualified type. Avoid using void* pointers.

  • To implement polymorphic interfaces, use pointers to base classes such as A* instead of void*.

  • To implement generic interfaces, use templates such as T* instead of void*.

Check Information

Group: Declarators
Category: Required, Non-automated