Main Content

MISRA C:2012 Rule 21.23

All operand arguments to any multi-argument type-generic macros declared in <tgmath.h> shall have the same standard type

Since R2024a

Description

Rule Definition

All operand arguments to any multi-argument type-generic macros declared in <tgmath.h> shall have the same standard type.

This rule comes from MISRA C™: 2012 Amendment 3.

Rationale

If you use the same standard type for all arguments to a type-generic macro, it becomes clear what type is used for evaluation of the macro expression.

For instance, if you use float variables for both arguments to the pow() macro, it is clear that evaluation of the macro expression adheres to the precision requirements of the float type. However, if one argument is float and the other double, it is unclear which type is used for the evaluation.

On platforms with extended real types, floating-point data types might not be ordered strictly by precision, so the type used for evaluation of the macro expression might actually lead to a loss of precision.

Polyspace Implementation

The rule checker reports violations if all arguments to a type-generic macro declared in tgmath.h do not have the same standard type (after integer promotion is applied to integer types). For example, the rule checker reports a violation:

  • If one argument has an integer type and another argument has a floating-point type.

  • If one argument has an integer type and another argument has a different integer type (after integer promotion is applied). For example, one argument might have type char, short or int, while another might have type long.

  • If one argument has an essentially real floating-point type and another argument has an essentially complex floating-point type. For more information on essential types, see MISRA C:2012 Rule 10.1.

  • If one argument has a floating-point type and another argument has a floating-point type of different size.

For some functions such as frexp, the final argument is meant for outputs. The rule checker skips this output argument when checking for rule violations.

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

In this example, the macro pow() is invoked four times.

  • The first three invocations are compliant with the rule because the macro arguments have the same data type (after integer promotion is applied to arguments of integer types).

    In the third invocation, the first argument has type int and the second argument has type char, which is promoted to int. Therefore, this invocation also complies with the rule.

  • The last invocation violates the rule because the first argument has type double and the second has type float.

#include <tgmath.h>

float fBase, fExp;
double dBase, dExp;
char cExp;
int iBase, iRes;
double res, dRes, fRes;

void calculatePower(void) { 
    fRes = pow(fBase, fExp);   //Compliant
    dRes = pow(dBase, dExp);   //Compliant
    iRes = pow(iBase, cExp);   //Compliant
    res = pow(dBase, fExp);    //Noncompliant
}

Check Information

Group:Standard Libraries
Category: Required
AGC Category: Required

Version History

Introduced in R2024a