Today I was tasked to Lint an imported module. Things went all for the most part, typical Linting affair: resolving unreferenced variables, uninitialized variables, potentially unbounded string copy, etc. Then I came across this gem:
Info 818: Pointer parameter 'var' (line 123) could be declared as pointing to const
Looking at the log, I figured all I was missing was a const qualifier. Not that bad.
Looking at the code, the offending line looked like this:
const char **values
which looks..... correct.
I proceed onto consulting Google for the next 2 hours while scratching my head. Eventually I reviewed the C const usage:
const char *ptr; // ptr is volatile, content of ptr is const
char * const ptr; // ptr is const, content of ptr volatile
const char * const ptr; // ptr is const, content of ptr is also const
Looking at the code closely, **values represents a table of strings, thus:
*table = table[0]; // pointer to the first string in the table
**table = table[0][0]; // points to the first byte of the first string in the table
The function in question performs string comparison by iterating through all strings in the table via:
tables++; // go to the next string
But since pointer to the strings are not modified (ie. *table or table[i]), Lint was effectively complaining that the API could be further qualified as:
const char * const * values // because *table is never modified
I then went a bit further and tried:
const char * const * const values // let's also make table itself const
and confirmed that the following line now generates an error:
table++; // this is now illegal
But since the function was defined as a callback to hook into another 3rd party library, I was unable to make the change as Lint suggested and had to purposely violate the const requirement to silence Lint:
*table = *table; // Lint now thinks *table has been updated.
But hey, I learnt something interesting today!
No comments:
Post a Comment