...
Code Block |
---|
void foo(int x) { x = 3; /* persistsvisible only untilin the function exits */ /* ... */ } |
Pointers behave in a similar fashion. A function may change a pointer to reference a different object, or NULL
, yet that change is discarded once the function exits. Consequently, declaring a pointer as const
is unnecessary.
Code Block |
---|
void foo(int *x) { x = NULL; /* persistsVisible only untilin the function exits */ /* ... */ } |
Noncompliant Code Example
...
If the function parameter is const
-qualified, any attempt to modify the pointed-to value results in a fatal diagnosticshould cause the compiler to issue a diagnostic message.
Code Block | ||||
---|---|---|---|---|
| ||||
void foo(const int *x) { if (x != NULL) { *x = 3; /* compiler should generatesgenerate compilerdiagnostic errormessage */ } /* ... */ } |
As a result, the const
violation must be resolved before the code can be compiled without a diagnostic message being issued.
Compliant Solution
This compliant solution addresses the const
violation by not modifying the constant argument:
...
Code Block | ||||
---|---|---|---|---|
| ||||
char *strcat_nc(char *s1, char *s2); char *c_str1 = "c_str1"; const char *c_str2 = "c_str2"; char c_str3[9] = "c_str3"; const char c_str4[9] = "c_str4"; strcat_nc(c_str3, c_str2); /* Compiler warns that c_str2 is const */ strcat_nc(c_str1, c_str3); /* Attempts to overwrite string literal! */ strcat_nc(c_str4, c_str3); /* Compiler warns that c_str4 is const */ |
The function behaves the same as strcat()
, but the compiler generates warnings in incorrect locations and fails to generate them in correct locations.
In the first strcat_nc()
call, the compiler generates a warning about attempting to cast away const on c_str2
because strcat_nc()
does not modify its second argument yet fails to declare it const
.
In the second strcat_nc()
call, the compiler compiles the code with no warnings, but the resulting code will attempt to modify the "c_str1"
literal. This violates STR05-C. Use pointers to const when referring to string literals and STR30-C. Do not attempt to modify string literals.
In the final strcat_nc()
call, the compiler generates a warning about attempting to cast away const
on c_str4
, which is a valid warning.
...
Code Block | ||||
---|---|---|---|---|
| ||||
char *strcat(char *s1, const char *s2); char *c_str1 = "c_str1"; const char *c_str2 = "c_str2"; char c_str3[9] = "c_str3"; const char c_str4[9] = "c_str4"; strcat(c_str3, c_str2); /* Args reversed to prevent overwriting string literal */ strcat(c_str3, c_str1); strcat(c_str4, c_str3); /* Compiler warns that c_str4 is const */ |
The const
-qualification of the second argument s2
eliminates the spurious warning in the initial invocation but maintains the valid warning on the final invocation in which a const
-qualified object is passed as the first argument (which can change). Finally, the middle strcat()
invocation is now valid, as c_str3
is a valid destination string and may be safely modified.
...
CERT C++ Secure Coding Standard | DCL13-CPP. Declare function parameters that are pointers to values not changed by the function as const |
ISO/IEC TR 24772:2013 | Passing Parameters and Return Values [CSJ] |
ISO/IEC 9899:2011 | Annex I "Common Warnings" |
...