Стандартизация языка программирования с и системы unix

Изменения по сравнению с C99

Последний черновик от 11 апреля 2011 года включает следующие изменения в языке C99 и спецификации библиотеки:

  • Выравнивание данных. Для этого в язык добавили спецификатор , оператор , функцию и заголовочный файл ;
  • Спецификатор функции ;
  • Выражения, не зависящие от типа (Type-generic expressions) с использованием ключевого слова . Например, следующий макрос вычисления кубического корня транслируется в , или в зависимости от типа параметра :
#define cbrt(X) _Generic((X), long double: cbrtl, \
                              default: cbrt, \
                              float: cbrtf)(X)
  • Поддержка многопоточности, для этого в стандарт добавили спецификатор типа , заголовочный файл , включающий в себя функции по созданию и управлению потоками, мьютексами, мониторами и функции управления хранилищем потока (англ. en:Thread-local storage). Также в C11 добавили квалификатор типа и заголовочный файл для атомарных операций доступа к памяти;
  • Улучшенная поддержка Unicode, основанная на техническом отчете C Unicode Technical Report ISO/IEC TR 19769:2004 (типы и для хранения данных в кодировках UTF-16/UTF-32, функции преобразования, находящиеся в заголовочном файле и соответствующие префиксы и перед строковыми литералами, как и префикс для строк в кодировке UTF-8);
  • Функция , признанная устаревшей, удалена из текущей ревизии стандарта языка Си (ISO/IEC 9899:1999/Cor.3:2007(E));
  • Интерфейсы для проверки границ массива (англ. en:Bounds checking, Annex K). ;
  • Возможности анализирования (англ. Analyzability features, Annex L);
  • Добавлено больше макросов для получения характеристик чисел с плавающей точкой, касающихся денормализованных чисел и максимального числа десятичных цифр, которые можно хранить без потери точности;
  • Анонимные структуры и объединения, используемые для вложения структур и объединений, например, .
  • Статические утверждения (англ. ), которые лучше, чем команды препроцессора и , потому что утверждение вычисляется в более поздней стадии трансляции, когда компилятор «знает», что какого типа;
  • Привилегированный режим создания и открытия (англ. exclusive create-and-open mode) для функции . Этот режим аналогичен режимам POSIX и обычно используется для ;
  • Функция  — третья функция для завершения программы, с минимальной деинициализацией значений, если завершить программу функцией не удается;
  • Макросы для создания комплексных чисел (были добавлены потому, что код мог не привести к ожидаемому значению, если мнимая часть была бесконечной или «не числом» (NaN)).

Бонусное правило: прекратите переизобретать clamp, int_to_string и string_to_int

Функция std::clamp дополняет функции min и max. Она обрезает значение и сверху, и снизу. Аналогичная функция доступна в более ранних версиях C++.

Правило «не переизобретайте clamp» можно обобщить: в любом крупном проекте избегайте дублирования маленьких функции и выражений для округлений, обрезаний значений и т.п. — просто один раз добавьте это в свою библиотеку.

Аналогичное правило работает для задач обработки строк. У вас есть своя маленькая библиотека для строк и парсинга? В ней есть парсинг или форматирование чисел? Если есть, замените свою реализацию на вызовы to_chars и from_chars

Функции и поддерживают обработку ошибок. Они возвращают по два значения:

  • первое имеет тип или соответственно и указывает на первый code unit (т.е. char или wchar_t), который не удалось обработать
  • второе имеет тип и сообщает подробную информацию об ошибке, пригодную для выброса исключения std::system_error

Поскольку в прикладном коде способ реакции на ошибку может различаться, следует помещать вызовы to_chars и from_chars внутрь своих библиотек и утилитных классов.

SUSv4 и POSIX. 1-2008

В 2008 году Austin Group завершила пересмотр объединенной спецификации POSIX. 1 и Single UNIX. Как и предшествующая версия стандарта, она состоит из основной спецификации, дополненной XSI-расширением. Эту редакцию мы будем называть SUSv4.

Изменения в SUSv4 не столь масштабные, как в SUSv3. Из наиболее существенных можно выделить следующие.

  • Добавлены новые спецификации для некоторых функций. Из их числа популярны , , , , , , и . Другие новые функции предназначены для работы с файлами и практически являются аналогами существующих функций (например, ). Они отличаются лишь тем, что относительный путь к файлу разрешается относительно каталога, на который ссылается дескриптор открытого файла, а не относитльно текущего рабо­чего каталога процесса.
  • Некоторые функции, указанные в SUSv3 как необязательные, становятся обязатель­ной частью стандарта в SUSv4. Например, отдельные функции, составлявшие в SUSv3 часть XSI-расширения, в SUSv4 стали частью базового стандарта. Среди функций, ставших обязательными в SUSv4, можно назвать функции, входящие в API сигналов режима реального времени, в API POSIX-таймеров, в API   и в API POSIX-семафоров.
  • Кое-какие функции из SUSv3 в SUSv4 помечены как устаревшие. К их числу относятся , , , , , и .
  • Спецификации некоторых функций, помеченных в SUSv3 как устаревшие, из SUSv4 удалены. Среди них , и .
  • Различные особенности существующих в SUSv3 спецификаций претерпели изме­нения в SUSv4. Например, к списку функций, от которых требуется обеспечение безопасной обработки асинхронных сигналов, добавились дополнительные функции.

Первые стандарты POSIX

Термин POSIX (аббревиатура от Portable Operating System Interface) обозначает группу стандартов, разработанных под руководством Института инженеров электротехники и электроники — Institute of Electrical and Electronic Engineers (IEEE), а точнее, его комитета по стандартам для портируемых приложений — Portable Application Standards Committee (PASC). Цель PASC-стандартов — содействие портиру­емости приложений на уровне исходного кода.

Название POSIX было предложено Ричардом Столлманом (Richard Stallman). Последняя буква X появилась потому, что названия большинства вариантов UNIX заканчивались на X. В стандарте указывалось, что название должно произноситься как pahzicks, наподобие слова positive («положительный»).

Для нас в стандартах POSIX наибольший интерес представляет первый стандарт POSIX, который назывался POSIX. 1 (или в более полном виде POSIX 1003.1), и после­дующий стандарт POSIX.2.

POSIX. 1 и POSIX.2

POSIX. 1 стал IEEE-стандартом в 1988 году и после небольшого количества пересмотров был принят как стандарт ISO в 1990 году (ISO/IEC 9945-1:1990). (Полных версий POSIX нет в свободном доступе, но их можно приобрести у IEEE)

POSIX. 1 сначала основывался на более раннем (1984 года) неофициальном стандарте, вы­работанном объединением поставщиков UNIX под названием /usr/group.

В POSIX. 1 документируется интерфейс прикладного программирования (API) для набора сервисов, которые должны быть доступны программам из соответствующей опе­рационной системы. ОС, способная справиться с этой задачей, может быть сертифици­рована в качестве совместимой с POSIX. 1.

POSIX. 1 основан на системном вызове UNIX и API библиотечных функций языка С, но при этом не требует, чтобы с этим интерфейсом была связана какая-либо конкретная реализация. Это означает, что интерфейс может быть реализован любой операционной системой и не обязательно UNIX. Фактически некоторые поставщики добавили API к своим собственным операционным системам, сделав их совместимыми с POSIX. 1, в то же время оставив сами ОС в практически неизменном виде.

Большое значение приобрели также расширения исходного стандарта POSIX. 1. Стандарт IEEE POSIX 1003.1b (POSIX.lb, ранее называвшийся POSIX.4 или POSIX 1003.4), одо­бренный в 1993 году, содержит расширения базового стандарта POSIX для работы в режиме реального времени. Стандарт IEEE POSIX 1003.1с (POSIX. 1с), одобренный в 1995 году, со­держит определения потоков в POSIX. В 1996 году была разработана пересмотренная версия стандарта POSIX.l (ISO/IEC 9945-1:1996), основной текст которой остался без изменений, но в него были внесены дополнения, касающиеся работы в режиме реального времени и ис­пользования потоков. Стандарт IEEE POSIX 1003. lg (POSIX. lg) определил API для работы в сети, включая сокеты. Стандарт IEEE POSIX 1003.Id (POSIX.Id), одобренный в 1999 году, и POSIX. lj, одобренный в 2000 году, определили дополнительные расширения основного стандарта POSIX для работы в режиме реального времени.

Расширения POSIX.lb для работы в режиме реального времени включают файловую син­хронизацию, асинхронный ввод/вывод, диспетчеризацию процессов, высокоточные часы и таймеры, а также обмен данными между процессами с применением семафоров, совмест­но используемой памяти и очереди сообщений. Префикс POSIX часто применяется для трех методов обмена данными между процессами, чтобы их можно было отличить от похожих, но более старых методов реализации семафоров, совместного использования памяти и оче­редей сообщений из System V.

Родственный стандарт POSIX.2 (1992, ISO/IEC 9945-2:1993) затрагивает оболочку и раз­личные утилиты UNIX, включая интерфейс командной строки компилятора кода языка С.

FIPS 151-1 и FIPS 151-2

FIPS является аббревиатурой от федерального стандарта обработки информации — Federal Information Processing Standard. Это название набора стандартов, разработанных правитель­ством США и используемых гражданскими правительственными учреждениями. В 1989 году был опубликован стандарт FIPS 151-1, основанный на стандарте 1988 года IEEE

POSIX.1 и предварительной версии стандарта ANSI С. Основное отличие FIPS 151-1 от POSIX. 1 (1988 года) заключалось в том, что по стандарту FIPS требовалось наличие кое- каких функций, которые в POSIX. 1 оставались необязательными. Поскольку основным покупателем компьютерных систем было правительство США, большинство поставщиков обеспечили совместимость своих UNIX-систем с FIPS 151-1-версией стандарта POSIX.1.

Стандарт FIPS 151-2 совмещен с редакцией 1990 ISO стандарта POSIX.1, но в осталь­ном остался без изменений. Уже устаревший FIPS 151-2 был отменен в феврале 2000 года.

Новые направления в развитии статических анализаторов кода

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

Но можно попасть и в уже известные ловушки из-за того, что их диагностика в новых конструкциях C++0x реализована намного хуже или вообще не реализована. Рассмотрим небольшой пример, демонстрирующий использование неинициализированной переменной:

Программист может надеяться получить предупреждение от компилятора как в первом, так и во втором случае. Но в примере с лямбда-функцией никакого предупреждения выдано не будет (испытано на Visual Studio 2010 RC, /W4). Как не было ранее и многих других предупреждений на различные опасные ситуации. Требуется время на реализацию подробной диагностики.

Можно ожидать новый виток развития статических анализаторов, с точки зрения поиска потенциально опасных конструкций, которые возникают при использовании конструкций C++0x. Мы позиционируем наш продукт PVS-Studio как средство для проверки современных программ. В настоящий момент мы понимаем под этим 64-битные и параллельные технологии. В будущем мы планируем провести исследования вопроса о том, какие потенциальные проблемы можно ожидать при использовании C++0x. Если подводных камней будет достаточно много, то возможно мы приступим к созданию нового инструмента для их диагностики.

Язык программирования C++

Последнее обновление: 03.08.2020

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

Своими корнями он уходит в язык Си, который был разработан в 1969—1973 годах в компании Bell Labs программистом Деннисом Ритчи (Dennis Ritchie).
В начале 1980-х годов датский программист Бьерн Страуструп (Bjarne Stroustrup), который в то время работал в компании Bell Labs, разработал С++ как расширение
к языку Си. Фактически вначале C++ просто дополнял язык Си некоторыми возможностями объектно-ориентированного программирования. И поэтому сам Страуструп вначале называл его
как «C with classes» («Си с классами»).

Впоследствии новый язык стал набирать популярность. В него были добавлены новые возможности, которые делали его не просто дополнением к Си, а совершенно новым языком программирования.
В итоге «Си с классами» был переименован в С++. И с тех по оба языка стали развиваться независимо друг от друга.

С++ является мощным языком, унаследовав от Си богатые возможности по работе с памятью. Поэтому нередко С++ находит свое применение в системном программировании, в частности, при создании операционных систем, драйверов, различных утилит,
антивирусов и т.д. К слову сказать, ОС Windows большей частью написана на С++. Но только системным программированием применение данного языка не
ограничивается. С++ можно использовать в программах любого уровня, где важны скорость работы и
производительность. Нередко он применяется для создания графических приложений, различных прикладных программ. Также особенно часто его используют для создания игр с
богатой насыщенной визуализацией. Кроме того, в последнее время набирает ход мобильное направление, где С++ тоже нашел свое применение. И даже в веб-разработке
также можно использовать С++ для создания веб-приложений или каких-то вспомогательных сервисов, которые обслуживают веб-приложения. В общем С++ — язык широкого пользования, на котором можно создавать практически любые виды программ.

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

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

Основные этапы развития

В 1979-80 годах Бьерн Страуструп разработал расширение к языку Си — «Си с классами». В 1983 язык был переименован в С++.

В 1985 году была выпущена первая коммерческая версия языка С++, а также первое издание книги «Языка программирования C++»,
которая представляла первое описание этого языка при отсутствии официального стандарта.

В 1989 была выпущена новая версия языка C++ 2.0, которая включала ряд новых возможностей. После этого язык развивался относительно медленно вплоть до 2011 года. Но при этом
в 1998 году была предпринята первая попытка по стандартизации языка организацией ISO (International Organiztion for Standartization). Первый стандарт
получил название ISO/IEC 14882:1998 или сокращенно С++98. В дальнейшем в 2003 была издана новая версия стандарта C++03.

В 2011 году был издан новый стандарт C++11, который содержал множество добавлений и обогащал язык С++ большим числом новых функциональных
возможностей. После этого в 2014 году было выпущено небольшое добавление к стандарту, известное также как C++14.
И еще один ключевой релиз языка намечен на 2017.

Компиляторы и среды разработки

Также для создания программ можно использовать интегрированные среды разработки IDE, такие как Visual Studio, Netbeans, Eclipse, Qt и т.д.

Вперед

Стандарт ANSI

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

В сравнении с некоторыми другими языками (например Java) стандартная библиотека крайне мала. Библиотека обеспечивает поддержку основного набора математических функций, обработку строк, конвертацию типов, файловый и консольный ввод-вывод. Она не содержит стандартный набор «контейнерных типов» как стандартная библиотека шаблонов языка C++, компоненты для работы с графическим пользовательским интерфейсом (GUI), сетью и прочей разнообразной функциональности, которую Java поддерживает по стандарту. Главным преимуществом маленькой стандартной библиотеки является упрощение работы с окружением ANSI Си по сравнению с другими языками, а следовательно и упрощение портирования программ на языке Си на новые платформы.

Множество прочих библиотек было разработано для поддержки схожей функциональности, обеспечиваемой другими языками в их стандартных библиотеках. Например, в проекте разработки окружения рабочего стола GNOME был разработан набор графических инструментов GTK+ и GLib — библиотека контейнерных структур данных, как впрочем и множество других известных примеров. Разнообразие доступных библиотек означает, что некоторые инструменты верхнего уровня, со временем подтвердили свою полезность. Значительным минусом является то, что они часто не слишком успешно взаимодействуют друг с другом, поэтому программистам зачастую привычнее работать с различными наборами библиотек, а их наборы могут быть доступны на различных специфических платформах.

Библиотечные заголовочные файлы ANSI Си c дополнениями C99 и C11

<assert.h> Содержит макрос утверждений, используемый для обнаружения логических и некоторых других типов ошибок в отлаживаемой версии программы.
<complex.h> Набор функций для работы с комплексными числами. (Появилось в C99)
<ctype.h> Содержит функции, используемые для классификации символов по их типам или для конвертации между верхним и нижним регистрами независимо от используемой кодировки (обычно ASCII или одно из её расширений, хотя есть и реализации, использующие EBCDIC).
<errno.h> Для проверки кодов ошибок, возвращаемых библиотечными функциями.
<fenv.h> Для управления средой, использующей числа с плавающей точкой. (Появилось в C99)
<float.h> Содержит заранее определенные константы, описывающие специфику реализации свойств библиотеки для работы с числами с плавающей точкой, как, например, минимальная разница между двумя различными числами с плавающей точкой (_EPSILON), максимальное число цифр точности (_DIG) и область допустимых чисел (_MIN, _MAX).
<inttypes.h> Для точной конвертации целых типов. (Появилось в C99)
<iso646.h> Для программирования в кодировке ISO 646. (Появилось в NA1)
<limits.h> Содержит заранее заданные константы, определяющие специфику реализации свойств целых типов, как, например, область допустимых значений (_MIN, _MAX).
<locale.h> Для setlocale() и связанных констант. Используется для выбора соответствующего языка.
<math.h> Для вычисления основных математических функций
<setjmp.h> Объявляет макросы setjmp и longjmp, используемые для нелокальных переходов
<signal.h> Для управления обработкой сигналов
<stdarg.h> Для доступа к различному числу аргументов, переданных функциям.
<stdbool.h> Для булевых типов данных. (Появилось в C99)
<stdint.h> Для определения различных типов целых чисел. (Появилось в C99)
<stddef.h> Для определения нескольких стандартных типов и макросов.
<stdio.h> Реализует основные возможности ввода и вывода в языке Си. Этот файл содержит весьма важную функцию .
<stdlib.h> Для выполнения множества операций, включая конвертацию, генерацию псевдослучайных чисел, выделение памяти, контроль процессов, окружения, сигналов, поиска и сортировки.
<string.h> Для работы с различными видами строк.
<tgmath.h> Для типовых математических функций. (Появилось в C99)
<threads.h> Заголовочный файл <threads.h> наряду с <stdatomic.h> предоставляет поддержку для параллельного программирования. (Появилась в C11)
<time.h> Для конвертации между различными форматами времени и даты.
<wchar.h> Для обработки «широких» потоков и нескольких видов строк при помощи «широких» символов (поддержка набора языков). (Появилось в NA1)
<wctype.h> Для классификации «широких» символов. (Появилось в NA1)

История

Первый стандарт языка C был опубликован ANSI. Через некоторое время он был принят международной организацией по стандартизации ISO, продолжившей выпускать следующие версии стандарта, которые стали приниматься как стандарт и институтом ANSI. Несмотря на это стандарт до сих пор чаще называют ANSI C, а не ISO C.

C89

В 1983 году Американский национальный институт стандартов сформировал комитет X3J11 чтобы установить спецификации стандарта C. Стандарт был завершен в 1989 году и ратифицирован как ANSI X3.159-1989 «Язык программирования C.» Эта версия языка часто упоминается как «ANSI C», или «C89» (чтобы отличить её от C99).

C90

В 1990 году, стандарт ANSI C был принят Международной организацией по стандартизации (ISO) как ISO/IEC 9899:1990, с изменениями форматирования. Эту версию иногда называют C90. Однако, термины C89 и C90 относятся в сущности к одному языку.

Этот стандарт был отозван как ANSI/INCITS, так и ISO/IEC.

C95

В 1995 году ISO (International Organization for Standardization) опубликовала расширение, названное Поправкой 1, для стандарта ANSI-C. Его полное имя было ISO / IEC 9899 / AMD1: 1995 или коротко — C95. Помимо исправления ошибок были внесены изменения в языковые возможности, такие как:

  • Улучшена многобайтная и широкосимвольная поддержка символов в стандартной библиотеке, введены и
  • Добавление диграфов
  • Спецификация стандартных макросов для альтернативной спецификации операторов, например для
  • Спецификация стандартного макроса

В дополнение к поправке, два технических исправления были опубликованы ISO для C90:

  • ISO/IEC 9899 TCOR1 в 1995 году
  • ISO/IEC 9899 TCOR2 в 1996 году

Тест препроцессора для совместимости с C95

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199409L

/* C95 compatible source code. */
#elif defined(__ANSI__)
/* C89 compatible source code. */
#endif

C99

В марте 2000 года ANSI принял стандарт ISO/IEC 9899:1999. Этот стандарт обычно называют C99. Включает некоторые примечательные дополнения к предыдущему стандарту:

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

ISO для C99 опубликовали три технических исправления:

  • ISO/IEC 9899:1999/Cor.1:2001(E)
  • ISO/IEC 9899:1999/Cor.2:2004(E)
  • ISO/IEC 9899:1999/Cor.3:2007(E)

C11

C11 — текущий стандарт языка С, принятый в 2011 году как ISO/IEC 9899:2011. Функции включают в себя улучшенную поддержку Unicode, с использованием нового ключевого слова , межплатформенный многопоточный API () и поддержку атомных типов как на основном языке, так и на библиотеке ().

Другие родственные ISO публикации

В рамках процесса стандартизации ISO также публикует технические отчеты и спецификации, относящиеся к языку C:

  • ISO/IEC TR 19769:2004, on library extensions to support Unicode transformation formats, integrated into C11
  • ISO/IEC TR 24731-1:2007, on library extensions to support bounds-checked interfaces, integrated into C11
  • ISO/IEC TR 18037:2008, on embedded C extensions
  • ISO/IEC TR 24732:2009, on decimal floating point arithmetic, superseded by ISO/IEC TS 18661-2:2015
  • ISO/IEC TR 24747:2009, on special mathematical functions,
  • ISO/IEC TR 24731-2:2010, on library extensions to support dynamic allocation functions
  • ISO/IEC TS 17961:2013, on secure coding in C
  • ISO/IEC TS 18661-1:2014, on IEC 60559:2011-compatible binary floating-point arithmetic
  • ISO/IEC TS 18661-2:2015, on IEC 60559:2011-compatible decimal floating point arithmetic
  • ISO/IEC TS 18661-3:2015, on IEC 60559:2011-compatible interchange and extended floating-point types
  • ISO/IEC TS 18661-4:2015, on IEC 60559:2011-compatible supplementary functions

Дополнительные технические спецификации находятся в разработке и ожидании утверждения, включая пятую и заключительную часть TS 18661, спецификацию транзакционной памяти программного обеспечения и параллельные расширения библиотек.

Зачем нужен C++11?

Бьёрн Страуструп охарактеризовал цели C++11 следующим образом:

   Укрепить сильные стороны языка C++, нежели пытаться захватить те области, в которых язык С++ слаб (например, приложения Windows с тяжелым графическим интерфейсом). Сосредоточиться на том, чтобы заставить язык С++ делать еще лучше то, что у него и так хорошо получается.

   Сделать язык C++ легче в изучении, использовании и обучении, предоставить функционал, который сделает язык более простым в использовании.

Руководствуясь этими целями, комитет, который согласовывал версию С++11, постарался выполнить следующее:

   Поддерживать стабильность и совместимость со старыми версиями языков C++ и Cи (насколько это возможно). Программы, которые работали под C++03 должны работать и под C++11.

   Свести к минимуму количество основных расширений языка С++. Внести большую часть изменений в Стандартную библиотеку С++ (эта цель не была достигнута в полной мере).

   Сосредоточиться на улучшении механизмов абстракции (классы, шаблоны), нежели на добавлении механизмов обработки конкретных случаев (которые случаются нечасто).

   Повысить безопасность типов данных.

   Повысить производительность и позволить языку C++ напрямую работать с оборудованием.

   Рассмотреть вопросы юзабилити и экосистемы. Язык C++ должен хорошо работать с другими инструментами, быть простым в использовании, обучении и т.д.

C++11 не слишком далеко ушел от C++ 03, но он действительно привнес много нового функционала.

decltype

В ряде случаев полезно «скопировать» тип некоторого объекта. Ключевое слово «auto» выводит тип, основываясь на выражении, используемом для инициализации переменной. Если инициализация отсутствует, то для определения типа выражения во время компиляции может быть использовано ключевое слово «decltype». Пример кода, где переменная «value» будет иметь тип, возвращаемый функцией «Calc()»:

Можно использовать «decltype» для объявления типа:

Учтите, что тип, взятый с использованием decltype, может отличаться от типа, выведенного с помощью auto.

Перейдем к примеру, где «decltype» может быть полезен с точки зрения 64-битности. Функция IsPresent ищет элемент в последовательности и возвращает «true» если он найден:

Данная функция неспособна работать в 64-битной системе с большими массивами. Если переменная arraySize будет иметь значение больше UINT_MAX, то условие «i < arraySize» никогда не выполнится и возникнет вечный цикл.

Если мы воспользуемся ключевым словом «auto», то это ничего не изменит:

Переменная «i» будет иметь тип «int», так как 0 имеет тип «int». Правильным исправлением может стать использование «decltype»:

Теперь счетчик «i» имеет тип «size_t» как и переменная «arraySize».

Поддержка «decltype» в библиотеке VivaCore во многом схожа с поддержкой «auto». Добавлена новая лексема tkDECLTYPE. Добавлена функция парсинга rDecltype в файле Parser.cc. В связи с появлением новой лексемы модификации подверглась функция optIntegralTypeOrClassSpec. Появился новый класс LeafDECLTYPE.

Для кодирования типа возвращаемого оператором «decltype» выбрана литера ‘X’ (заглавная буква ‘X’, в отличие от прописной ‘x’, используемой для auto). В связи с этим изменилась функциональность классов TypeInfo и Encoding. Например, функции WhatIs, IsDecltype, MakePtree.

Функциональность по вычислению типов для оператора «decltype» реализована в классе Environment и входит в состав библиотеки VivaCore. Вычисление типа осуществляется в момент записи новой переменной/типа в Environment (функции RecordTypedefName, RecordDeclarator, RecordConstantDeclarator). За вычисление типа отвечает функция FixIfDecltype.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector