Const до или const после?
Для начала вы, вероятно, знаете, что const
может использоваться для того, чтобы либо данные объекта, либо указатель не изменялись или оба.
const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer
Однако вы также можете использовать синтаксис:
Object const *obj; // same as const Object* obj;
Единственная вещь, которая, кажется, имеет значение, - какая сторона звездочки вы поместите ключевое слово const
. Лично я предпочитаю помещать const
слева от типа, чтобы указать, что данные не изменяемы, поскольку я считаю, что это лучше читается в моем мышлении слева направо, но какой синтаксис появился первым?
Что еще более важно, почему существуют два правильных способа указания данных const
и в какой ситуации вы бы предпочли или нуждались друг в друге, если они есть?
Edit:
Итак, похоже, что это было произвольное решение, когда стандарт того, как компиляторы должны интерпретировать вещи, был составлен задолго до моего рождения. Поскольку const
применяется к тому, что слева от ключевого слова (по умолчанию?), Я предполагаю, что они полагали, что не было вреда при добавлении "ярлыков", чтобы применять ключевые слова и типы классификаторов другими способами, по крайней мере, до тех пор, пока не будет изменения декларации путем разбора a * и...
Так было в C, а затем я предполагаю?
Ответы
Ответ 1
"почему существует два правильных способа указания данных const и в какой ситуации вы бы предпочли бы или нуждались бы друг в друге, если они есть?"
По сути, причина, по которой позиция const
внутри спецификаторов перед звездочкой не имеет значения, заключается в том, что C-грамматика была определена таким образом Керниганом и Ричи.
Причина, по которой они определили грамматику таким образом, вероятно, что их компилятор C проанализировал ввод слева направо и завершил обработку каждого токена, поскольку он его потреблял. Использование токена *
изменяет состояние текущего объявления на тип указателя. Встреча const
после *
означает, что квалификатор const
применяется к объявлению указателя; столкнувшись с ним до *
, означает, что квалификатор применяется к указанным данным.
Поскольку семантическое значение не изменяется, если квалификатор const
появляется до или после спецификаторов типа, он принимается в любом случае.
Аналогичный случай возникает при объявлении указателей функций, где:
void * function1(void)
объявляет функцию, которая возвращает void *
,
void (* function2)(void)
объявляет указатель на функцию, которая возвращает void
.
Снова замечание заключается в том, что синтаксис языка поддерживает парсер слева направо.
Ответ 2
Правило:
const относится к тому, что осталось от него. Если в левой части ничего нет, то это относится к тому, что нужно от него.
Я предпочитаю, чтобы const, стоящий справа от объекта, был const, потому что это был "оригинальный" способ const.
Но я думаю, что это очень субъективная точка зрения.
Ответ 3
Я предпочитаю второй синтаксис. Это помогает мне отслеживать "что" является постоянным, читая объявление типа справа налево:
Object * const obj; // read right-to-left: const pointer to Object
Object const * obj; // read right-to-left: pointer to const Object
Object const * const obj; // read right-to-left: const pointer to const Object
Ответ 4
Порядок ключевых слов в объявлении не все, что исправлено. Существует много альтернатив "одному истинному порядку". Как этот
int long const long unsigned volatile i = 0;
или он должен быть
volatile unsigned long long int const i = 0;
??
Ответ 5
Первое правило - использовать формат, который соответствует вашим местным стандартам кодирования
требует. После этого: установка const
впереди ведет к концу
путаница, когда задействованы typedefs, например:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
Если ваш стандарт кодирования позволяет typedef указателей, то это действительно
должен настаивать на том, чтобы положить const после типа. В каждом случае, но
когда применяется к типу, const должен следовать тому, к чему он относится, поэтому
Когерентность также утверждает в пользу const после. Но локальное кодирование
руководящие принципы превзошли все эти; разница обычно не важна
достаточно, чтобы вернуться и изменить весь существующий код.
Ответ 6
Существуют исторические причины, по которым либо левое, либо право допустимо. Stroustrup добавил const к С++ к 1983 году, но он не дошел до C до C89/C90.
В С++ есть веская причина всегда использовать const справа. Вы будете везде согласованы, потому что функции const member должны быть объявлены следующим образом:
int getInt() const;