...
Unlike passed-by-value arguments and pointers, pointed-to values are a concern. A function may modify a value referenced by a pointer argument, leading to a side effect which persists even after the function exits. Modification of the pointed-to value is not diagnosed by the compiler, which assumes this was the intended behavior.
Code Block | ||||
---|---|---|---|---|
| ||||
void foo(int *x) { if (x != NULL) { *x = 3; /* visible outside function */ } /* ... */ } |
If the function parameter is const
-qualified, any attempt to modify the pointed-to value results in a fatal diagnostic.
Code Block | ||||
---|---|---|---|---|
| ||||
void foo(const int *x) { if (x != NULL) { *x = 3; /* generates compiler error */ } /* ... */ } |
...
This compliant solution addresses the const violation by not modifying the constant argument.
Code Block | ||||
---|---|---|---|---|
| ||||
void foo(const int * x) { if (x != NULL) { printf("Value is %d\n", *x); } /* ... */ } |
...
This noncompliant code example defines a fictional version of the standard strcat()
function called strcat_nc()
. This function differs from strcat()
in that the second argument is not const
-qualified.
Code Block | ||||
---|---|---|---|---|
| ||||
char *strcat_nc(char *s1, char *s2); char *str1 = "str1"; const char *str2 = "str2"; char str3[9] = "str3"; const char str4[9] = "str4"; strcat_nc(str3, str2); /* Compiler warns that str2 is const */ strcat_nc(str1, str3); /* Attempts to overwrite string literal! */ strcat_nc(str4, str3); /* Compiler warns that str4 is const */ |
...
This compliant solution uses the prototype for the strcat()
from C90. Although the restrict
type qualifier did not exist in C90, const
did. In general, function parameters should be declared in a manner consistent with the semantics of the function. In the case of strcat()
, the initial argument can be changed by the function while the second argument cannot.
Code Block | ||||
---|---|---|---|---|
| ||||
char *strcat(char *s1, const char *s2); char *str1 = "str1"; const char *str2 = "str2"; char str3[9] = "str3"; const char str4[9] = "str4"; strcat(str3, str2); /* Args reversed to prevent overwriting string literal */ strcat(str3, str1); strcat(str4, str3); /* Compiler warns that str4 is const */ |
...