For reading complex pointer declarations there is the right-left rule.
But this rule does not mention how to read const
modifiers.
For example in a simple pointer declaration, const
can be applied in several ways:
char *buffer; // non-const pointer to non-const memory
const char *buffer; // non-const pointer to const memory
char const *buffer; // equivalent to previous declartion
char * const buffer = {0}; // const pointer to non-const memory
char * buffer const = {0}; // error
const char * const buffer = {0}; // const pointer to const memory
Now what about the use of const
with a pointer of pointer declaration?
char **x; // no const;
const char **x;
char * const *x;
char * * const x;
const char * const * x;
const char * * const x;
const char * const * const x;
And what is an easy rule to read those declarations? Which declarations make sense?
Is the Clockwise/Spiral Rule applicable?
Two real world examples
The method ASTUnit::LoadFromCommandLine
uses const char **
to supply command line arguments (in the llvm clang source).
The argument vector parameter of getopt()
is declared like this:
int getopt(int argc, char * const argv[], const char *optstring);
Where char * const argv[]
is equivalent to char * const * argv
in that context.
Since both functions use the same concept (a vector of pointers to strings to supply the arguments) and the declarations differ - the obvious questions are: Why do they differ? Makes one more sense than the other?
The intend should be: The const
modifier should specify that the function does not manipulate strings of this vector and does not change the structure of the vector.