#c #c 17 #language-lawyer #declaration
#c #c 17 #язык-юрист #объявление
Вопрос:
В разделе dcl.meaning говорится:
Таким образом, объявление определенного идентификатора имеет вид
T D
, где T имеет вид attribute-specifier-seq opt decl-specifier-seq, а D является декларатором. Ниже приведена рекурсивная процедура для определения типа, указанного для содержащегося идентификатора декларатора с помощью такого объявления.
[пуля 6] В объявлении T D, где D имеет форму
( D1 )
, тип содержащегося идентификатора декларатора совпадает с типом содержащегося идентификатора декларатора в объявлении
T D1
Круглые скобки не изменяют тип встроенного идентификатора декларатора, но они могут изменять привязку сложных деклараторов.
Однако рассмотрим приведенный ниже код
int main(){
int* (ptr) = nullptr;
}
В моем примере (ptr)
соответствует форме (D1)
, однако это не декларатор, полный декларатор в моем примере *ptr
. Согласно пуле, упомянутой выше, (D1)
обозначает D
, D
является декларатором объявления (обратите внимание на выделенную часть), то есть (D1)
должен быть декларатором объявления. Только форма int (*ptr)
соответствует тому, о чем говорится в пуле 6. Кажется, что маркер 6 не охватывает пример int* (ptr)
. Итак, как интерпретировать такой случай? каков тип такого декларатора-id( int* (ptr)
). Если я неправильно понимаю пункт 6, как правильно понять пункт 6? Или пуля 6 является дефектом формулировки, которая игнорирует такой случай?
Ответ №1:
Вы должны перейти к следующему разделу. Пункт 6 — это всего лишь один случай, который здесь неприменим, потому что ваше объявление не имеет формы T (D1)
. Он имеет вид T D
with T = int
и D = *(ptr)
. D = *D1
(сопоставление здесь с D1 = (ptr)
) обрабатывается [dcl.ptr]
:
В объявлении,
T D
гдеD
, имеет вид*attribute-specifier-seq_opt cv-qualifier-seq_opt D1
и тип идентификатора в объявлении
T D1
равен «derived-declarator-type-list T
«, тогда тип идентификатораD
является «производным-декларатором-типом-списком cv-квалификатором-следующим указателем наT
«. cv-квалификаторы применяются к указателю, а не к объекту, на который указано. Аналогично, необязательный атрибут-спецификатор-seq относится к указателю, а не к объекту, на который указано.
Итак, чтобы узнать, что int *(ptr)
означает, мы сначала рассмотрим, что int (ptr)
означает. Теперь вступает в действие ваша цитата в [dcl.meaning]
, в которой говорится, что это то же самое, что int ptr
. Итак, int (ptr)
было бы объявить идентификатор ptr
как тип int
. Затем, согласно правилу, которое я процитировал, int *(ptr)
объявляется ptr
как указатель на int
.
Комментарии:
1. да, вы правы. [dcl.meaning] не намеревается охватывать
int *(ptr)
. Другими словами,(D1)
должен быть полный декларатор, что является случаем, описанным [dcl.meaning]2. Еще один вопрос. почему предложение не является
where D is the form (D1)
? В моем понимании,where D has the form (D1)
означает, что*(ptr)
это также ситуация, о которой говорится в предложении. Принимается(ptr)
как(D1)
, принимается*(ptr)
какD
, где D включает(D1)
.3. Это просто не то, что означают эти слова.
*(ptr)
не имеет формы (не соответствует шаблону)(D1)
. Точка.*(ptr)
имеет синтаксический подтерм, который имеет эту форму (соответствует этому шаблону), в частности(ptr)
, но(ptr)
не*(ptr)
, и это просто не имеет значения, если какое-либо другое правило не делает это важным.