В C , C ++ , и D языки программирования , а тип Классификатор является ключевым словом , которое применяется к типу , в результате квалифицированного типа. Например, const int
это квалифицированный тип, представляющий постоянное целое число, а int
соответствующий неквалифицированный тип - просто целое число. В D они известны как конструкторы типов , по аналогии с конструкторами в объектно-ориентированном программировании .
Квалификаторы типа - это способ выражения дополнительной информации о значении через систему типов и обеспечение правильности использования данных. Квалификаторы типов обычно не используются за пределами семейства языков C / C ++: во многих языках есть понятие констант, но это выражается в том, что привязка имени является константой («переменная, которая не меняется»), а не через систему типов. ; см. альтернативы ниже.
По языку [ править ]
C / C ++ [ править ]
По состоянию на 2014 год [Обновить]и C11 в стандарте C есть четыре квалификатора типа: const
( C89 ), volatile
( C89 ), restrict
( C99 ) и _Atomic
( C11 ) - последний имеет частное имя, чтобы избежать конфликтов с именами, определяемыми пользователем. [1] Первые два из них, const
и volatile
, также присутствуют в C ++ и являются единственными квалификаторами типа в C ++. Таким образом, в C ++ термин « cv -квалифицированный тип» (для c onst и v olatile) часто используется для «квалифицированного типа», в то время как термины « c -qualified type» и « v-qualified type "используются, когда релевантен только один из квалификаторов.
Из них, const
безусловно, самый известный и наиболее используемый, он встречается в стандартных библиотеках C и C ++ и встречается при любом значительном использовании этих языков, которое должно удовлетворять константной корректности . Другие квалификаторы используются для низкоуровневого программирования и, хотя и широко используются там, редко используются типичными программистами. Однако какое-то время volatile
некоторые программисты на C ++ использовали для синхронизации во время потоковой передачи, хотя это не поощрялось и теперь не работает в большинстве компиляторов.
D [ править ]
В D конструкторы типов являются const
, immutable
, shared
, и inout
. immutable
является более сильным вариантом const
, обозначающим данные, которые никогда не могут изменить свое значение, а const
обозначает данные, которые не могут быть изменены с помощью этой ссылки: это постоянное представление о возможно изменяемых данных. shared
используется для общих данных в многопоточности (как volatile
это кратко использовалось в C ++). inout
- это подстановочный знак, позволяющий функциям, которые не изменяют данные (и, следовательно, относятся только к неквалифицированному типу данных), возвращать тот же уточненный тип, что и входные данные. const
а immutable
также может использоваться как спецификатор класса хранения.
Синтаксис [ править ]
В C и C ++ тип задается в объявлении функции или объявлении переменной путем предоставления одного или нескольких спецификаторов типа и, необязательно, квалификаторов типа. Например, целочисленная переменная может быть объявлена как:
int x ;
где int
- спецификатор типа. Целочисленная переменная без знака может быть объявлена как:
беззнаковый int x ;
где оба unsigned
и int
являются спецификаторами типа. Постоянная целочисленная переменная без знака может быть объявлена как:
const unsigned int x ;
где const
представляет собой тип классификатор, который квалифицированный типа x
IS const unsigned int
и неквалифицированный типа unsigned int
.
Объявления переменных дополнительно имеют необязательный спецификатор класса хранения . Собственно, это отдельная тема, отличная от типа, хотя const
объявление переменной также имеет значение для класса хранения, а именно то, что она может храниться в постоянной памяти.
Изменчивая правильность [ править ]
Другой квалификатор в C и C ++ volatile
указывает, что объект может быть изменен чем-то внешним по отношению к программе в любое время, и поэтому его необходимо повторно считывать из памяти при каждом обращении к нему.
Квалификатор чаще всего встречается в коде, который напрямую управляет оборудованием (например, во встроенных системах и драйверах устройств ) и в многопоточных приложениях (хотя часто используется неправильно в этом контексте; см. Внешние ссылки в изменчивой переменной ). Его можно использовать точно так же, как const
в объявлениях переменных, указателей, ссылок и функций-членов, и, фактически, volatile
иногда используется для реализации аналогичной стратегии проектирования по контракту, которую Андрей Александреску называет volatile
-корректностью, [2] хотя это встречается гораздо реже, чем const
-правильность. volatile
Классификатор также может быть разделconst_cast
, и его можно комбинировать с const
квалификатором, как в этом примере:
// Устанавливаем ссылку на аппаратный регистр, доступный только для чтения, // который отображается в жестко запрограммированной области памяти. const volatile int & hardwareRegister = * reinterpret_cast < int *> ( 0x8000 );int currentValue = hardwareRegister ; // Считываем адрес в памяти int newValue = hardwareRegister ; // Прочитать еще разhardwareRegister = 5 ; // Ошибка, невозможно записать в константную локацию
Потому что hardwareRegister
это volatile
, нет никакой гарантии , что он будет держать то же значение на два последовательных чтения , даже если программист не может изменить его. Семантика здесь указывает, что значение регистра доступно только для чтения, но не обязательно неизменным.
История [ править ]
Понятие квалификатора типа было введено вместе с примером readonly
(позже переименованного const
) Бьярном Страуструпом во внутреннем техническом меморандуме Bell Labs 1981 г. [3] и реализовано на языке C с классами , предшественнике C ++ . [4] Что касается мотивации, Страуструп пишет: [4]
- «Он выполнял две функции: как способ определения символической константы, которая подчиняется правилам области и типа (то есть без использования макроса), и как способ считать объект в памяти неизменным».
const
затем был принят в C как часть стандартизации и появился в C89 (и последующих версиях) вместе с другим квалификатором типа volatile
, который был изобретен комитетом по стандартизации ANSI C (X3J11). [5] volatile
появились к 1985 году; [6], и раннее использование заключалось в компиляции ядра UNIX для MIPS , чтобы позволить оптимизировать компиляцию, предотвращая применение обычных оптимизаций к изменчивым переменным. [7] На noalias
заседании комитета X3J11 в декабре 1987 г. был предложен еще один уточняющий аргумент, но он был отклонен; его цель была в конечном итоге достигнута restrict
квалификацией в C99. Мотивация noalias
была дополнительна кvolatile
, а именно, что это указывает на то, что могут быть выполнены даже обычно небезопасные оптимизации. Ричи не очень поддерживал классификаторы типов, утверждая, что они не «несут их вес», но в конечном итоге не выступал за их исключение из стандарта; [8] он выступил против noalias
, и это было исключено из проекта.
Java не имеет квалификаторов типов и явно опущена const
: предложение 1999 года о ее добавлении было отклонено, особенно потому, что добавление его постфактум и последующее изменение стандартной библиотеки для ее последовательного использования нарушило бы совместимость. [9] Однако изначально Java оставила открытой возможность реализации const
, заметную в том, что const
это зарезервированное слово , хотя на самом деле оно не используется в качестве ключевого слова . Вместо этого в Java есть объектно-ориентированное ключевое слово final
, которое используется для определения атрибутов (а затем и для локальных переменных) как постоянных, но не для определения типов.
Альтернативы [ править ]
Другие языки используют другой подход, считая постоянство свойством идентификатора (или привязки имени ), а не типом. Таким образом, такие языки имеют постоянные идентификаторы (соответствующие «переменным», которые не меняются) с одним присваиванием, но не имеют понятия константной корректности: поскольку постоянство не является частью типа, нет возможности несоответствия типов. Примеры включают Ada 83 с постоянными объектами и constant
ключевым словом, [10] [a] и Java с final
ключевым словом.
Заметки [ править ]
- ^ Стандарт Ады называет это « зарезервированным словом »; см. эту статью для использования.
Ссылки [ править ]
- ^ C11: Новый стандарт C , Томас Слива
- ^ "Generic <Programming>: volatile - лучший друг многопоточного программиста Volatile-Correctness или как заставить ваш компилятор определять условия гонки для вас" Андрея Александреску в журнале пользователей C / C ++ Форум экспертов C ++
- ^ Бьярне Страуструп , "Расширения языка C Type Concept.", Bell Labs внутренний технический меморандум, 5 января 1981.
- ^ a b Соперничество братьев и сестер: C и C ++ , Бьярн Страуструп , 2002, стр. 5
- ^ Dennis M. Ritchie , « Развитие языка С Архивированного 2015-01-10 в Archive.today », 2003: «X3J11 также представило множество мелких дополнений и корректировок, например, классификаторы типа константное и изменчив , и немного другие правила продвижения типа ".
- ↑ Он появляется в примечаниях к техническому докладу Европейской группы пользователей систем UNIX (EUUC) «Проект стандарта ANSI для языка программирования C» Майка Банахана, 13 сентября 1985 г., как напечатано в информационном бюллетене группы пользователей систем Unix Австралии (AUUGN). ), Том 6, №6 , с. 73
- ^ Энциклопедическая статья (16 августа 1991). «Re: RISC против CISC? Назовите вещи своими именами?» . Группа новостей : comp.arch . Usenet: [email protected] .
- ^ "Позвольте мне начать с того, что я не уверен, что даже квалификаторы до декабря ('const' и 'volatile') имеют свой вес; я подозреваю, что то, что они добавляют к стоимости изучения и использования языка, не вознаграждаются большей выразительностью. «Volatile», в частности, является украшением для эзотерических приложений и гораздо лучше выражается другими средствами. Его главное достоинство в том, что почти каждый может о нем забыть. «Const» одновременно более полезен и навязчив; вы не можете не узнать об этом из-за его присутствия в интерфейсе библиотеки. Тем не менее, я не выступаю за исключение квалификаторов, хотя бы потому, что уже слишком поздно ».
- ^ JDK-4211070: Java должна поддерживать константные параметры (например, C ++) для поддержки кода [ sic ]
- ^ 1815A , 3.2.1. Объявления объекта :
«Объявленный объект является константой, если зарезервированное слово« константа »появляется в объявлении объекта; тогда объявление должно включать явную инициализацию. Значение константы не может быть изменено после инициализации. Формальные параметры режима подпрограмм и записей , и общие формальные параметры режима в, также являются константами; параметр цикла - это константа в соответствующем цикле; подкомпонент или срез константы является константой ».
Внешние ссылки [ править ]
- C11 стандарт
- Конструкторы типов