статические и изменчивые классификаторы после типа

Бьярне объясняет, почему const может идти до или после типа.

http://www.stroustrup.com/bs_faq2.html#constplacement

"const T" and "T const" were - and are - (both) allowed and equivalent.
[...]

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

Моей непосредственной мыслью было: «Хорошо, это имеет смысл, но если это причина, то почему Const Special?» Видимо это не так. И clang, и gcc не выдают никаких предупреждений о следующем.

int volatile myint;
int static myotherint;

Имеет смысл, что это будет допустимо, но я никогда не видел, чтобы этот синтаксис использовался или даже упоминался как возможность. Размещает ли статические и изменчивые квалификаторы после допустимого типа C ++?

Как определить это по тексту Стандарта?

3

Решение

Эти части на самом деле довольно широко разделены в стандарте. static класс хранения, как указано в §7.1.1 / 1:

storage-class-specifier:
register
static
thread_local
extern
mutable

Это используется в Децл спецификатор, как определено в §1.7:

decl-specifier:
storage-class-specifier
type-specifier
function-specifier
friend
typedef
constexpr

decl-specifier-seq:
decl-specifier attribute-specifier-seqopt
decl-specifier decl-specifier-seq

Таким образом, это позволяет либо static int или же int static указать тип. Аналогично, вы можете объявить функцию друга как friend int f(); или же int friend f();,

const или же volatile может участвовать, только когда вы на самом деле что-то объявляете, так что это подпадает под «деклараторы» в § 8. Эта часть грамматики достаточно длинная, я слишком ленив, чтобы все это отформатировать, но она определяет INIT-описатель-лист на верхнем уровне, то описатель, и (пропуская несколько уровней) сводится к cv-qualifier который либо const или же volatile, По крайней мере, на мой взгляд, это в основном позволяет const или же volatile быть свободно смешанным с другими вещами, которые определяют тип.

2

Другие решения

Да, этот синтаксис в порядке. Первая часть декларации грамматики представляет собой последовательность Децл-спецификаторы. К ним относятся классы хранения, спецификаторы типов, функции, friend, typedef, а также constexpr, Грамматика позволяет им появляться в любом порядке. Однако наложенные на них семантические правила вводят некоторые ограничения. Например, в объявлении переменной всегда должен быть один спецификатор типа, который не является квалификатором cv (const или же volatile). Также никогда не должно быть более одного спецификатора класса хранения (кроме thread_local может появиться с static или же extern).

Обратите внимание, что последовательность спецификаторов decl идет перед любым синтаксисом составного типа, таким как указатели, ссылки, массивы и т. Д. Например, последовательность decl-спецификаторов отмечена в следующих примерах:

static const int *p;
|              |

char volatile static *(&p)[20];
|                  |

Обратите внимание, что volatile это как cv-квалификатор constИтак, причины, позволяющие volatile в приведенном вами примере такие же, как для const, Эти ключевые слова могут также появляться глубже в декларации (как в int *volatile x;).

По соглашению, мы сначала пишем спецификацию класса хранения, затем — спецификацию типа и cv-квалификаторы, где это уместно. Я предпочитаю писать свои cv-квалификации после спецификаторы типа, которым они соответствуют, так как они более последовательны.

Вы можете прочитать Что такое объявления и деклараторы и как их типы интерпретируются стандартом?.

4

ну, вот что я думаю. я пытаюсь это интерпретировать.

static int *ptr1;
int* static ptr2;

Первый означает, что это указатель, указывающий на статическое целое число.
второй означает, что это статическая переменная с типом целочисленного указателя.

я думаю, что другой путь должен иметь аналогичную интерпретацию.

0
По вопросам рекламы [email protected]