Массив объявлен без размера и постоянных летучих - PullRequest
0 голосов
/ 12 октября 2018

Я нашел эту строку в своем рабочем проекте, но не могу понять:

extern const volatile uint8 * const volatile array[];

Не могли бы вы помочь мне объяснить строку?

1 Ответ

0 голосов
/ 12 октября 2018

Во-первых, пропуская квалификаторы:

uint8 *array[];

array - это массив неопределенного размера, элементы которого имеют тип uint8 *.Другими словами, массив указателей на uint8.

Если это объявление появляется как параметр функции, синтаксис массива фактически является сокращением для указателя.Если это не параметр функции и он объявлен в области видимости файла, это действует как предварительное определение .Полное определение может встречаться в другом месте кода, который указывает размер и, необязательно, инициализатор.Если другого полного определения не существует, то массив определен так, чтобы иметь 1 элемент.

Прежде чем говорить о том, что означает объявление с квалификаторами, давайте сначала поговорим о том, что конкретно означают эти квалификаторы.

Спецификатор const не позволяет коду изменять именованный объект.С учетом этого объявления:

const int x;

Это означает, что x нельзя изменить, используя, например, x = 1.С указателями это немного сложнее:

const int *x;

Это определяет x как указатель на const int.Это означает, что вы можете изменить x, но не то, на что он указывает.Так что x = &y допустимо, но не *x = 1.

int * const x;

Это определяет x как const указатель на int, что означает, что вы не можете изменить x, но выможет изменить то, на что он указывает.Таким образом, x = &y не является допустимым, но *x = 1 является.

const int * const x;

Это определяет x как const указатель на const int.Таким образом, в этом случае, x и то, на что он указывает, не могут быть изменены.

const int * const x[];

Здесь x - это массив, элементы которого являются const указателями на const int.Как и в предыдущем примере, для каждого элемента массива нельзя изменить ни элемент массива, ни то, на что он указывает.

Теперь давайте поговорим о volatile.Этот классификатор сообщает компилятору, что рассматриваемая переменная может измениться непредсказуемо.Из раздела 6.7.3p7 стандарта C :

Объект, имеющий тип volatile-qualified, может быть изменен способами, неизвестными для реализации, или иметь другие неизвестные побочные эффекты.Поэтому любое выражение, относящееся к такому объекту, должно оцениваться строго в соответствии с правилами абстрактной машины, как описано в 5.1.2.3.Кроме того, в каждой точке последовательности значение, сохраненное последним в объекте, должно соответствовать значению, предписанному абстрактной машиной, за исключением случаев, когда оно изменено неизвестными факторами, упомянутыми ранее. 134) То, что составляет доступ к объекту, имеющему тип, определяемый volatile, определяется реализацией

134) Объявление volatile может использоваться для описания объекта, соответствующего памяти.сопоставленный порт ввода / вывода или объект, доступ к которому осуществляется с помощью асинхронно прерываемой функции.Действия над объявленными объектами не должны быть "оптимизированы" реализацией или переупорядочены, за исключением случаев, разрешенных правилами для оценки выражений

. Это означает, что объект volatile может изменяться неизвестна компилятору, и, следовательно, компилятор не должен выполнять какие-либо оптимизации для этой переменной и фактически должен предполагать, что значение было изменено извне.

Теперь перейдем к полному объявлению:

const volatile uint8 * const volatile array[];

Это объявляет array как массив неопределенного размера, элементы которого имеют тип uint8 *, где элементы массива не могут быть изменены программой (т. Е. const), но могут быть изменены извне (т. Е. volatile) и то, на что указывают эти элементы массива, также не может быть изменено программой, но может быть изменено извне.

...