...
In this noncompliant example, the C Standard Library function function strchr()
is is called through the function pointer pointer fp
with with incorrectly typed arguments. According to the C Standard, subclause 6.3.2.3 paragraph 8 [ISO/IEC 9899:2011],
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 type, the behavior is undefined.
(See also also undefined behavior 26 in in Annex J of the C Standard.)
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; } |
Noncompliant Code Example
In this noncompliant example, the C Standard Library function strchr()
is declared with the correct arguments. This code still exhibits undefined behavior, but most compilers will warn that the arguments passed to fp
do not match its declaration.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <string.h> char *(*fp)(const char *, int); int main(void) { const char *c; fp = strchr; c = fp('e', "Hello"); printf("%s\n", c); return 0; } |
...
In this compliant solution, the function pointer fp
points to a function returning char *
with the is invoked with the correct number and type of arguments:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdio.h> #include <string.h> char *(*fp)(const char *, int); int main(void) { const char *c; fp = strchr; c = fp("Hello",'e'); printf("%s\n", c); return 0; } |
Noncompliant Code Example
In this noncompliant example, the function copy()
is defined to take three arguments but is called with two arguments:
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* In another source file */ #include <string.h> void copy(char *dst, const char *src, size_t size) { if (strncpy(dst, src, size) == 0) { /* Report error */ } } /* Copy prototype in scope in this source file */ void copy(char *dst, const char *src, size_t size); void g(const char *s) { enum { BUFFERSIZE = 20 }; char buf[BUFFERSIZE]; copy(buf, s, BUFFERSIZE); } |
Noncompliant Code Example
In this noncompliant example, the function buginf()
is defined to take a variable number of arguments and expects them all to be signed integers, with a sentinel value of -1
:
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* In another source file */ void buginf(const char *fmt, ...) { /* ... */ } /* buginf prototype in scope in this source file */ void buginf(const char *fmt, ...); void h(void) { buginf("bug in function %s, line %d\n", "h", __LINE__); /* ... */ } |
Noncompliant Code Example
In this noncompliant example, the function f()
is defined to take an argument of type long
, but f()
is called from another file with an argument of type int
:
...