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;