...
The C Standard identifies five two distinct situations in which undefined behavior (UB) may arise as a result of invoking a function using a declaration that is incompatible with its definition or by supplying incorrect types or numbers of arguments:
| UB | Description | ||
A pointer is used to call a function whose type is not compatible with the referenced type (6.3.2.3). | |||
A function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function | For a call to a function without a function prototype in scope, the number of arguments does not equal the number of parameters (6.5.2.2). | ||
For a call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2). | |||
| For a call to a function without a function prototype in scope where the function is not defined with a function prototype, the types of the arguments after promotion are not compatible with those of the parameters after promotion (with certain exceptions) (6.5.2.2). | |||
A function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function (6.5.2.2). |
Functions that are appropriately declared (as in DCL40-C. Do not create incompatible declarations of the same function or object) will typically generate a compiler diagnostic message if they are supplied with the wrong number or types of arguments. However, there are cases in which supplying the incorrect arguments to a function will, at best, generate compiler warnings. Although such warnings should be resolved, they do not prevent program compilation. (See MSC00-C. Compile cleanly at high warning levels.)
Noncompliant Code Example
The header <tgmath.h> provides type-generic macros for math functions. Although most functions from the <math.h> header have a complex counterpart in <complex.h>, several functions do not. Calling any of the following type-generic functions with complex values is undefined behavior.
Functions That Should Not Be Called with Complex Values
Functions that are appropriately declared (as in DCL40-C. Do not create incompatible declarations of the same function or object) will typically generate a compiler diagnostic message if they are supplied with the wrong number or types of arguments. However, there are cases in which supplying the incorrect arguments to a function will, at best, generate compiler warnings. Although such warnings should be resolved, they do not prevent program compilation. (See MSC00-C. Compile cleanly at high warning levels.)
Noncompliant Code Example
The header <tgmath.h> provides type-generic macros for math functions. Although most functions from the <math.h> header have a complex counterpart in <complex.h>, several functions do not. Calling any of the following type-generic functions with complex values is undefined behavior 205.
Functions That Should Not Be Called with Complex Values
atan2() | erf | fdim | fmin | ilogb | llround | logb | nextafter | atan2() | erf | fdim | fmin | ilogb | llround | logb | nextafter | rint | tgamma |
cbrt | erfc | floor | fmod | ldexp | log10 | lrint | nexttoward | round | trunc | ||||||||
ceil | exp2 | fma | frexp | lgamma | log1p | lround | remainder | scalbn | |||||||||
copysign | expm1 | fmax | hypot | llrint | log2 | nearbyint | remquo | scalbln |
...
In this noncompliant example, the C standard library function strchr() is called through the function pointer fp declared with a prototype with incorrectly typed arguments. According to the C Standard, 6.3.2.3, paragraph 8 [ISO/IEC 9899:20112024]
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced the referenced type, the behavior is undefined.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <string.h>
char *(*fp)();
int main(void) {
const char *c;
fp = strchr;
c = fp('e', "Hello");
printf("%s\n", c);
return 0;
} |
...
Calling a function with incorrect arguments can result in unexpected or unintended program behavior.
Rule | Severity | Likelihood | Detectable | RepairableRemediation Cost | Priority | Level |
|---|---|---|---|---|---|---|
EXP37-C | Medium | Probable | No | HighNo | P4 | L3 |
Automated Detection
| Tool | Version | Checker | Description | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| incompatible-argument-type parameter-match parameter-match-computed parameter-match-type | Fully checked | ||||||||||||||||||||||||
| Axivion Bauhaus Suite |
| CertC-EXP37 | |||||||||||||||||||||||||
| CodeSonar |
| LANG.FUNCS.APM | Array parameter mismatch | ||||||||||||||||||||||||
| Compass/ROSE | Can detect some violations of this rule. In particular, it ensures that all calls to | ||||||||||||||||||||||||||
| Coverity |
| MISRA C 2012 Rule 8.2 MISRA C 2012 Rule 17.3 | Implemented Relies on functions declared with prototypes, allow compiler to checkcheck | ||||||||||||||||||||||||
| Cppcheck Premium |
| premium-cert-exp37-c | |||||||||||||||||||||||||
| CC2.EXP37 | Partially implemented | |||||||||||||||||||||||||
| EDG | |||||||||||||||||||||||||||
| GCC |
| Can detect violation of this rule when the | () example described earlierKlocwork | ||||||||||||||||||||||||
| Include Page | Klocwork_V | Klocwork_V | MISRA.FUNC.UNMATCHED.PARAMS | LDRA tool suite | |||||||||||||||||||||||
| Include Page | LDRA_V | LDRA_V | 41 D, 21 S, 98 S, 170 S, 496 S, 576 S | Partially implemented | Parasoft C/C++test | ||||||||||||||||||||||
| Include Page | Parasoft_V | Parasoft_V | CERT_C-EXP37-a | Identifiers shall be given for all of the parameters in a function prototype declaration |
| ||||||||||||||||||||||
| Helix QAC |
| C1331, C1332, C1333, C3002, C3320, C3335 C++0403 | |||||||||||||||||||||||||
| Klocwork |
| MISRA.FUNC.UNMATCHED.PARAMS | |||||||||||||||||||||||||
| LDRA tool suite |
| 41 D, 21 S, 98 S, 170 S, 496 S, 576 S | Partially implemented | ||||||||||||||||||||||||
| Parasoft C/C++test |
| CERT_C-EXP37-a | Conversions shall not be performed between non compatible pointer to a function types | ||||||||||||||||||||||||
| Polyspace Bug Finder |
| Checks for:
Rule partially covered. | Polyspace Bug Finder | ||||||||||||||||||||||||
| Include Page | Polyspace Bug Finder_V | Polyspace Bug Finder_V | Bad file access mode or status Format string specifiers and arguments mismatch Qualifier removed in conversion Standard function call with incorrect arguments | Access mode argument of function in Mismatch between function or variable declarations String specifiers do not match corresponding arguments Variable qualifier is lost during conversion Argument to a standard function does not meet requirements for use in the function Function pointer cast to another function pointer with different argument or return type All declarations of an object or function shall use the same names and type qualifiers Conversions shall not be performed between a pointer to a function and any other type A function shall not be declared implicitly | PRQA QA-C++ | 4.1 | 0403 | PRQA QA-C | |||||||||||||||||||
| Include Page | PRQA QA-C_v | PRQA QA-C_v | 1331, 1332, 1333, 3002, 3320, 3335 | Partially implemented||||||||||||||||||||||||
| PVS-Studio |
| V540, V541, V549, V575, V632, V639, V666, V671, V742, V743, V764, V1004 | |||||||||||||||||||||||||
| Security Reviewer - Static Reviewer |
| C71 | Fully implemented | ||||||||||||||||||||||||
| SonarQube C/C++ Plugin |
| S930 | Detects incorrect argument count | ||||||||||||||||||||||||
| RuleChecker |
| parameter-match parameter-match-type | Partially checked | ||||||||||||||||||||||||
| TrustInSoft Analyzer |
| RuleChecker
| RuleChecker
| parameter-match parameter-match-type | Partially checkedunclassified ("function type matches") | Partially verified (see one compliant and one non-compliant example). |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
- Wrong argument values or references
Bibliography
| [CVE] | CVE-2006-1174 |
| [ISO/IEC 9899:2011] | 6.35.2.32, "Pointers"Function Calls" |
| [ISO/IEC 9899:2024] | 6.53.2.23, "Function CallsPointers" |
| [IEEE Std 1003.1:2013] | open() |
| [Spinellis 2006] | Section 2.6.1, "Incorrect Routine or Arguments" |
...