stringtranslate.com

Тип квалификатора

Квалификатор типа — это аналог конструкторов в объектно-ориентированном программировании .

По языку

С/С++

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

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

Д

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

Синтаксис

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

int x ; 

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

беззнаковое целое число x ;  

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

константа беззнаковое целое число x ;   

где const— квалификатор типа, квалифицированный тип которого xconst unsigned int, а неквалифицированный тип — unsigned int.

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

Volatile-корректность

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

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

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

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

История

Понятие квалификатора типа было введено вместе с примером readonly(позже переименованным const) Бьярном Страуструпом во внутреннем техническом меморандуме Bell Labs 1981 года [3] и реализовано в языке C with Classes , предшественнике 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 есть ключевое слово object-oriented final, которое используется для квалификации атрибутов (и, следовательно, также для локальных переменных) как констант, но не для квалификации типов.

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

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

Примечания

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

Ссылки

  1. ^ C11: Новый стандарт языка Си, Томас Плам
  2. ^ «Generic<Programming>: volatile — лучший друг многопоточного программиста Изменчивая корректность или как заставить ваш компилятор определять состояния гонки за вас» Андрея Александреску в журнале C/C++ Users Journal на форуме экспертов C++
  3. Бьярне Страуструп , «Расширения концепции типов языка C», внутренний технический меморандум Bell Labs, 5 января 1981 г.
  4. ^ ab Соперничество братьев и сестер: C и C++, Бьярне Страуструп , 2002, стр. 5
  5. ^ Деннис М. Ритчи , «Развитие языка C». Архивировано 10 января 2015 г. на archive.today , 2003 г.: «X3J11 также ввел множество небольших дополнений и изменений, например, квалификаторы типов const и volatile , а также несколько иные правила продвижения типов».
  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. Объявления объектов:
    "Объявленный объект является константой, если зарезервированное слово const появляется в объявлении объекта; тогда объявление должно включать явную инициализацию. Значение константы не может быть изменено после инициализации. Формальные параметры режима in подпрограмм и записей, а также общие формальные параметры режима in также являются константами; параметр цикла является константой внутри соответствующего цикла; подкомпонент или срез константы является константой".

Внешние ссылки