Конст до или конст после? - PullRequest
118 голосов
/ 31 марта 2011

Для начала вы, вероятно, знаете, что 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 применяется к тому, что находится слева от ключевого слова (по умолчанию?), Я думаю, они решили, что не было никакого вреда в добавлении "горячих клавиш" для применения ключевых слов и определителей типов по крайней мере другими способами до тех пор, пока не изменится объявление путем разбора * или & ...

Так было и в Си, тогда я полагаю?

Ответы [ 6 ]

76 голосов
/ 31 марта 2011

почему есть два правильных способа указания const данных и в какой ситуации вы бы предпочли или нуждались в одном, а не в другом?

По сути, причина того, что позиция const в спецификаторах перед звездочкой не имеет значения, заключается в том, что грамматика C была определена таким образом Керниганом и Ричи.

Причиной, по которой они определили грамматику таким образом, было то, что их компилятор C проанализировал ввод слева направо и завершил обработку каждого токена, когда он его потреблял. Использование токена * изменяет состояние текущего объявления на тип указателя. Обнаружение const после * означает, что к объявлению указателя применяется квалификатор const; встреча с ним до * означает, что к указанным данным применяется квалификатор.

Поскольку семантическое значение не меняется, если квалификатор const появляется до или после спецификатора типа, он принимается в любом случае.

Аналогичный случай возникает при объявлении указателей на функции, где:

  • void * function1(void) объявляет функцию, которая возвращает void *,

  • void (* function2)(void) объявляет указатель на функцию на функцию, которая возвращает void.

Снова следует отметить, что синтаксис языка поддерживает синтаксический анализатор слева направо.

62 голосов
/ 31 марта 2011

Правило таково:

const относится к тому, что от него осталось.Если слева ничего нет, то это относится к вещу справа от него.

Я предпочитаю использовать const справа от вещи, чтобы быть const только потому, что это «оригинальный» способ, которым constопределено.

Но я думаю, что это очень субъективная точка зрения.

46 голосов
/ 31 марта 2011

Я предпочитаю второй синтаксис. Это помогает мне отслеживать «что» постоянно, читая объявление типа справа налево:

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
33 голосов
/ 31 марта 2011

Порядок ключевых слов в объявлении не так уж и фиксирован.Есть много альтернатив «единому истинному порядку».Как это

int long const long unsigned volatile i = 0;

или должно быть

volatile unsigned long long int const i = 0;

??

6 голосов
/ 31 марта 2011

Первое правило - использовать любой формат, который требует ваш местный стандарт кодирования.После этого: размещение const впереди не приводит к путанице, когда задействованы typedef, например:

typedef int* IntPtr;
const IntPtr p1;   // same as int* const p1;

Если ваш стандарт кодирования допускает указатели typedef для указателей, тогда он действительно должен настаивать на том,после типа.В любом случае, но применительно к типу, const должен следовать тому, к чему он применяется, поэтому согласованность также свидетельствует в пользу const после.Но местные правила кодирования превосходят все это;разница обычно не настолько важна, чтобы вернуться назад и изменить весь существующий код.

5 голосов
/ 23 сентября 2015

Существуют исторические причины, по которым приемлемо как левое, так и правое. Stroustrup добавил const в C ++ к 1983 году , но не добрался до C до C89 / C90.

В C ++ есть хорошая причина всегда использовать const справаВы будете последовательны везде, потому что функции-члены const должны быть объявлены следующим образом:

int getInt() const;
...