Main Content

MISRA C:2023 Rule 23.5

A generic selection should not depend on implicit pointer type conversion

Since R2024a

Description

Rule Definition

A generic selection should not depend on implicit pointer type conversion.

Rationale

The controlling expression of a generic selection undergoes an lvalue conversion and then the type of the converted value is compared to the types in the association list. Unless an exact match is found, the default association is selected. The compiler makes no attempt to implicitly convert the type of the controlling expression to match any of the nondefault association. If you implement a generic function using generic association, the argument of the generic function does not undergo implicit conversion, unlike with nongeneric C functions. This behavior can be unexpected and can produce incorrect results.

Polyspace Implementation

The rule checker reports a violation if the compiler performs an implicit pointer conversion between the type of the controlling expression and the type of the default association. If your selection is not based on pointer types, the rule checker does not report a violation.

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 function generic_func() is generic and uses a generic selection macro to select an action based on the type of its argument. The generic selection macro accounts for the types const long long*, const long*, and const int*. If the argument of generic_func() does not match one of these types exactly, then the default association is selected.

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int func_ll(const long long *);
int func_l(const long *);
int func_i(const int *);
int func_any(void *);
#define generic_func(x) (_Generic((x), const long long*: func_ll, const long*: func_l, const int*: func_i, default: func_any)(x))

int main() {
	int i = -5;
	long l = -10L;
	long long ll = -15LL;
	double d = -20.0;

	generic_func(&i);  //Noncompliant
	generic_func(&l);  //Noncompliant
	generic_func(&ll); //Noncompliant
	generic_func(&d);  //Noncompliant

	return 0;
}

In the function main(), the generic selection is done using types that requires implicit pointer type conversion. For example, &i has the type int*, which matches none of the type names in the association list for generic_func. Because the compiler performs no implicit pointer type conversion when invoking generic functions, generic_func(&i) results in a call to the function func_any() instead of func_i(). This can produce incorrect result. The rule checker reports violations for calls that require implicit pointer conversion.

Check Information

Group: Generic Selections
Category: Advisory
AGC Category: Advisory

Version History

Introduced in R2024a