Квалификатор типа - Type qualifier

в C, C ++, и D языки программирования, а квалификатор типа это ключевое слово который применяется к тип, в результате чего квалифицированный тип. Например, const int квалифицированный тип, представляющий постоянное целое число, а int - соответствующий неквалифицированный тип, просто целое число. В D они известны как конструкторы типов, по аналогии с конструкторы в объектно-ориентированном программировании.

Квалификаторы типа - это способ выражения дополнительной информации о значении через система типов, и обеспечение правильность в использовании данных. Квалификаторы типов обычно не используются за пределами семейства языков C / C ++: во многих языках есть понятие констант, но выражается это с помощью привязка имени постоянство («переменная, которая не меняется»), а не через систему типов; видеть альтернативы, ниже.

По языку

C / C ++

По состоянию на 2014 г. и C11, в стандарте C есть четыре квалификатора типа: const (C89 ), летучий (C89 ), ограничивать (C99 ) и _Атомный (C11 ) - последний имеет частное имя, чтобы избежать конфликтов с именами, определяемыми пользователем.[1] Первые два из них, const и летучий, также присутствуют в C ++ и являются единственными квалификаторами типа в C ++. Таким образом, в C ++ термин "резюме-квалифицированный тип "(для const и volatile) часто используется для обозначения "квалифицированного типа", а термины "c-квалифицированный тип "и"v-qualified type "используются, когда релевантен только один из квалификаторов.

Из этих, const на сегодняшний день является наиболее известным и наиболее часто используемым, появляющимся в C и C ++ стандартные библиотеки и встречается в любом значительном использовании этих языков, которое должно удовлетворять const-правильность. Другие квалификаторы используются для низкоуровневого программирования и, хотя и широко используются там, редко используются типичными программистами. Однако какое-то время летучий был использован некоторыми программистами на C ++ для синхронизации во время многопоточности, хотя это не поощрялось и теперь не работает в большинстве компиляторов.

D

В D конструкторы типов const, неизменный, общий, и inout. неизменный это более сильный вариант const, указывая данные, которые могут никогда изменить его значение, а const указывает данные, которые нельзя изменить с помощью этой ссылки: это константа Посмотреть на возможно изменяемых данных. общий используется для общих данных в многопоточности (как летучий кратко использовался в C ++). inout - это подстановочный знак, позволяющий функциям, которые не изменяют данные (и, следовательно, относятся только к неквалифицированному типу данных), возвращать те же самые квалифицированный введите в качестве ввода. const и неизменный также может использоваться как спецификатор класса хранения.

Синтаксис

В C и C ++ тип задается в функции декларация или объявление переменной, задав один или несколько спецификаторов типа и, необязательно, квалификаторов типа. Например, целочисленная переменная может быть объявлена ​​как:

int Икс;

куда int - спецификатор типа. Целочисленная переменная без знака может быть объявлена ​​как:

беззнаковый int Икс;

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

const беззнаковый int Икс;

куда const квалификатор типа, который квалифицирует тип Икс является const unsigned int и неквалифицированный тип беззнаковое целое.

Объявления переменных дополнительно имеют необязательный спецификатор класса хранения. Собственно это отдельная тема, отличная от типа, правда const в объявлении переменной также считается, что имеет значение для класса хранилища, а именно то, что он может храниться в постоянной памяти.

Летучая корректность

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

Квалификатор чаще всего встречается в коде, который напрямую управляет оборудованием (например, в встроенные системы и драйверы устройств ) И в многопоточный приложения (хотя часто используются неправильно в этом контексте; см. внешние ссылки на летучая переменная ). Его можно использовать точно так же, как const в объявлениях переменных, указателей, ссылок и функций-членов, и фактически, летучий иногда используется для реализации аналогичной стратегии разработки по контракту, которая Андрей Александреску звонки летучий-корректность,[2] хотя это встречается гораздо реже, чем const-корректность. В летучий квалификатор также может быть удален const_cast, и его можно комбинировать с const квалификатор, как в этом примере:

// Устанавливаем ссылку на аппаратный регистр только для чтения, который// отображается в жестко запрограммированной области памяти.const летучий int & оборудование  = *reinterpret_cast<int*>(0x8000);int текущая стоимость = оборудование; // Читаем адрес памятиint newValue = оборудование;     // Прочитать еще разоборудование = 5; // Ошибка, невозможно записать в константное местоположение

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

История

Было введено понятие квалификатора типа вместе с примером только чтение (позже переименован const) к Бьярне Страуструп во внутреннем техническом меморандуме Bell Labs 1981 г.,[3] и реализовано в C с классами, предшественник C ++.[4] Что касается мотивации, Страуструп пишет:[4]

«Он выполнял две функции: как способ определения символьной константы, которая подчиняется правилам области и типов (то есть без использования макроса), и как способ считать объект в памяти неизменным».

const затем был принят в C как часть стандартизации и появился в C89 (и последующие версии) вместе с другим квалификатором типа, летучий, который был изобретен комитетом по стандартизации ANSI C (X3J11).[5] летучий появился к 1985 г .;[6] и раннее использование заключалось в компиляции ядра UNIX для MIPS, чтобы обеспечить оптимизированную компиляцию, не допуская применения обычных оптимизаций к изменчивым переменным.[7] Дополнительный квалификатор, noalias, был предложен на заседании комитета X3J11 в декабре 1987 года, но отклонен; его цель была в конечном итоге достигнута ограничивать квалификатор в C99. Мотивация для noalias был дополнением к летучий, а именно, что это указывает на то, что могут быть выполнены даже обычно небезопасные оптимизации. Ричи не очень поддерживал классификаторы типов, утверждая, что они не «несут их вес», но в конечном итоге не выступал за их исключение из стандарта;[8] он выступал против noalias впрочем, и его исключили из проекта.

Java не имеет квалификаторов типов и явно опущена const: предложение 1999 года о его добавлении было отклонено, в частности, потому что добавление его постфактум и последующее изменение стандартной библиотеки для постоянного использования нарушило бы совместимость.[9] Однако изначально Java оставила открытой возможность реализации const, заметно в этом const это зарезервированное слово, хотя на самом деле он не используется в качестве ключевое слово. Вместо этого в Java есть объектно-ориентированное ключевое слово окончательный, который используется для определения атрибутов (а затем и для локальных переменных) как постоянных, но не для определения типов.

Альтернативы

Другие языки используют другой подход, считая постоянство свойством идентификатор (или же привязка имени ), а не тип. Таким образом, такие языки имеют постоянные идентификаторы (соответствующие «переменным», которые не меняются) с одним присваиванием, но не имеют понятия константной корректности: поскольку постоянство не является частью типа, нет возможности несоответствия типов. Примеры включают Ада 83 с постоянными объектами и постоянный ключевое слово,[10][а] и Java с окончательный ключевое слово.

Примечания

  1. ^ Стандарт Ada называет это "зарезервированное слово "; см. эту статью для использования.

Рекомендации

  1. ^ C11: Новый стандарт C, Томас Слива
  2. ^ "Generic : volatile - лучший друг многопоточного программиста Volatile-Correctness или как заставить ваш компилятор определять условия гонки за вас" Андрея Александреску в Журнал пользователей C / C ++ Форум экспертов C ++
  3. ^ Бьярне Страуструп, «Расширения концепции типов языка C», Внутренний технический меморандум Bell Labs, 5 января 1981 г.
  4. ^ а б Соперничество между братьями и сестрами: C и C ++, Бьярне Страуструп, 2002, с. 5
  5. ^ Деннис М. Ричи, "Развитие языка C В архиве 2015-01-10 в Archive.today ", 2003:" X3J11 также представил множество небольших дополнений и корректировок, например, квалификаторы типа const и летучий, и немного другие правила продвижения ".
  6. ^ Он появляется в примечаниях к техническому докладу Европейской группы пользователей систем UNIX (EUUC) «Проект стандарта ANSI для языка программирования C» Майка Банахана, 13 сентября 1985 г., как напечатано в информационном бюллетене группы пользователей систем UNIX Австралии (AUUGN) , Том 6, № 6, п. 73
  7. ^ Джон Маши (16 августа 1991 г.). «Re: RISC против CISC? Назовите вещи своими именами?». Группа новостейcomp.arch. Usenet:  [email protected].
  8. ^ "Позвольте мне начать с того, что я не уверен, что даже квалификаторы до декабря ('const' и 'volatile') имеют их вес; я подозреваю, что то, что они добавляют к стоимости изучения и использования языка, не окупается в большей выразительности. «Volatile», в частности, является украшением для эзотерических приложений, и его гораздо лучше выражать другими способами. Его главное достоинство в том, что почти каждый может о нем забыть. «Const» одновременно более полезен и навязчив; вы не могу не узнать об этом из-за его присутствия в интерфейсе библиотеки. Тем не менее, я не выступаю за искоренение квалификаторов, хотя бы потому, что уже слишком поздно ».
  9. ^ JDK-4211070: Java должна поддерживать константные параметры (например, C ++) для поддержки кода [sic]
  10. ^ 1815A, 3.2.1. Объявления объекта:
    "Объявленный объект является константой, если зарезервированная словесная константа появляется в объявлении объекта; тогда объявление должно включать явную инициализацию. Значение константы не может быть изменено после инициализации. Формальные параметры режима в подпрограммах и записях, а также общие формальные параметры режима in также являются константами; параметр цикла является константой внутри соответствующего цикла; подкомпонент или часть константы является константой ".

внешняя ссылка