Для чтения сложных указателей указателя существует право-левое правило.
Но это правило не упоминает, как читать модификаторы const
.
Например, в простой декларации указателя const
можно применять несколькими способами:
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
Как насчет использования const
с указателем объявления указателя?
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;
А что такое простое правило для чтения этих объявлений? Какие декларации имеют смысл?
Используется ли по часовой стрелке/спиральному правилу?
Два примера реального мира
Метод ASTUnit::LoadFromCommandLine
использует const char **
для предоставления аргументов командной строки (в источнике llvm clang).
Параметр параметра аргумента getopt()
объявляется следующим образом:
int getopt(int argc, char * const argv[], const char *optstring);
Где char * const argv[]
эквивалентно char * const * argv
в этом контексте.
Поскольку обе функции используют одну и ту же концепцию (вектор указателей на строки для аргументов), а декларации различаются - очевидные вопросы: почему они отличаются? Делает еще один смысл, чем другой?
Предполагается, что модификатор const
должен указать, что функция не управляет строками этого вектора и не меняет структуру вектора.