Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 203
Текст из файла (страница 203)
Код на С, не являющийся С++-кодом Разночтения С/С++, которые вызывают большинство проблем, не столь уж и сложны. Большинство их них легко обнаруживаются компилятором. В данном разделе приведены примеры на С, которые не соответствуют языку С++. Многие из них считаются устаревшими для современного С. В языке С большинство функций можно вызывать без предварительного объявления: l* не С++. В С - плохой стиль */ та(п () з(оибте и12 = з9гг (2) !* вызов необьявленной функции *! 949 8.2. Совместимость С и С++ рггпгу'("гйе взгиаге гоог о/ л 1в %д~п", з92); /* вызов необъявленной функции *! Последовательное использование предварительных объявлений (прототипов функций) рекомендуется и для языка С.
Когда этому следуют на практике (или когда компилятор имеет установки следить за этим), то проблем с переходом от С к С++ не возникает. Если же вызываются необъявленные функции, то нужно очень точно знать правила языка С, чтобы понять, где возникла проблема с переносимостью.
Например, функция тасе () из предыдущего примера содержит с точки зрения языка С по крайней мере две ошибки. В языке С функция, объявленная без аргументов, может принимать любое количество аргументов любого типа. Такой стиль стандартом С признан устаревшим, но он не так уж и редко встречается в реальных программах: чоЫ1(); /* не упомянуты типы аргументов */ чоЫя() ( 7(г); l * Не С++. Плохой стиль в С *l В языке С функции можно определять в стиле, когда типы объявляются после перечисления аргументов: чв1ау(а,р,е) сваг лрг Сваг ег ( l* ...
*/ ) /* С. Не СЬЬ *! Это лучше переписать в виде чоЫ/'(!пг а, сйаг* р, сйаг с) ( /* ... */ ) В языке С и в старых версиях С++ (предшествовавших принятию стандарта) типом по умолчанию является гпг. Например: сонм а = 7г /* В С подразумевается 1пг. Не С++ */ Поздняя спецификация С99 запрещает "умолчательные 1пг", как это имеет место в стандарте языке С++. Язык С допускает определения структур в объявлениях возврата функций или их аргументов. Например: лггисг В (1пг к,у; ) /'(); / * С. Не С++ * ! чоЫа(мгисгб (т(к,у; ) у); l* С.
Не С+э */ С точки зрения правил языка С++ для определения типов такие объявления бесполезны, а потому недопустимы. В С переменным перечислительного типа можно присваивать целые значения: епит 1)1геспоп (ир,йома); епит Р(гесаоп д = 1; !* еггог: гпг присваивается О!гесдоп; о)с в С */ В С++ гораздо больше ключевых слов, чем в С. Если какое-либо из них присутствует в С-программе как идентификатор, то во имя совместимости это нужно устранить. Ф Ф Ф Ф Ф 950 Приложение В.Совместимость Ключевые слова в С++ (но не в С) Ь!1апд Ьйог ' Ьоо1 аив) апИ ео Иупат!с сам ти!аЬ(е сагсл с1ат сотр! Ие1еге типе сопл! сат )г!ела ехр!!с!1 уа!ве ехрогг по! орегагог патеврасе ог риЬИс ог еу, ргггаге ргогесгед ге1игегрге! сав! маис сам гетр!аге ) !Ыв ) !ягою 1уред! ггие !гу )урепате ил!ие ' ютиа! юсЛаг ! хог хог ее В С некоторые из ключевых слов С++ являются макросами, определенными в стандартных заголовочных файлах: Ключевые слова С++ (макросы в С) иог ец ог ог ец !гие юсяаг г хог пог хог ец тг 1; !п! 1; l* определяет или объявляет единственную целую переменную 1; не С++ *I В С++ любая сущность определяется один раз (99.2.3).
В языке С++ класс не может иметь имя, совпадающее с именем, определенным оператором гуре!!е!' для ссылки на другой тип в той же самой области видимости (95.7). В языке С тип еоЫ* можно использовать в правой части операции присваивания или при инициализации переменной любого указательного типа; в С++ этого делать нельзя (95.б). Например; го!а у (1п! и ) ) т!* р = та!1ос (и~в!сев((!пг) ); !* не С++ */ ) Язык С разрешает переходы Ьюго к помеченным метками операторам ЩА.6) в обход инициализации, что запрещает делать язык С++.
В языке С глобальная константа по определению имеет внешнее связывание; в С++ это не так и ее требуется инициализировать, если только она не объявляется явно с модификатором ехгегп (95.4). В языке С имена вложенных структур располагаются в той же области видимости, что и объемлющая структура. Например: То есть в С они могут участвовать в проверках условных препроцессорных директив ИЩеУ переопределяться и т.д. В языке С глобальные объекты данных могут несколько раз объявляться в одной и той же единице трансляции без использования спецификатора ехгегл. Если инициапизатор присутствует только в одном из них, то объект считается определенным один раз.
Например: 8.2. Совместимость С и С++ 991 згги«т Я 1 мгие! Т 1/*... */]; /„, ]: зггиез Т х; /* ол в С - означает ЯнТл; Не С++ */ В С массив может инициализироваться инициализатором, в котором значений больше, чем элементов у массива. Например: ейаг »15] = «Озеаг"; /* о/г в С, терминальный нуль не используется. Не С++ */ В.2.3. Нежелательные особенности Помечая ту или иную особенность языка как незаелательную (Нергесаге4, комитет по стандартизации выражает желание устранить ее. Однако у комитета нет права удалить из языка широко используемые средства (как бы избыточны или опасны они не были).
Эти пометки служат настоятельным советом программисту избегать помеченные особенности. Ключевое слово лапе, которое в общем случае означает «статическое вьшеление памяти», может использоваться и для индикации факта, что функция или объект локальны по отношению к единице трансляции. Например; ///йеН згапс ии д!оЬ» ///]]е2: ззаяс Ьм 8!оЬ г Эта программа имеет две целые переменные с именем а!оЬ. Каждая из этих д!оЬ используется исключительно функциями из их единицы трансляции. Применение згапе для отражения свойства «локально для единицы трансляции» помечено в С++ как нежелательное (дергесагед). Вместо этого следует применять неименованные пространства имен (58.2.5.1).
Неявное приведение из строкового литерала в (неконстантный) сйаг* также объявлено нежелательным. Используйте именованные массивы элементов типа ейаг, или избегайте присваивания строковых литералов переменным типа еЬаг* (85.2.2). Приведение типа в стиле языка С также помечено как нежелательное, ибо в языке С++ введены новые операции приведения типа. Программисты должны отнестись к этому серьезно. Там, где требуются явные приведения типа, операции жале еазг, гезагегргег сам, евам еазг или их комбинации делают все необходимое. Новые операции приведения (по сравнению с приведением в стиле С) точнее отражают их назначение и более заметны в тексте программы (96.2.7).
В.2.4. Код на С++, не являющийся кодом на С Здесь перечисляются средства Ст+, отсутствующие в языке С. Они отсортированы по назначению. На самом деле, их можно классифицировать по-разному и многие средства служат нескольким целям, так что к данной классификации не стоит относиться слишком серьезно. 952 Приложение В. Совместимость ° Средства, предназначенные в первую очередь для удобства записи: ° Средства, предназначенные в первую очередь для усиления системы типов: 1.
2. 3. 4. 5. Логический тип Ьоо! (04.2); частично добавляется в С99 б. Новый синтаксис приведения типов (06.2.7) ° Средства, связанные с пользовательскими типами; 1. Классы (глава 10) 2. Функции-члены 810.2.1) и вложенные классы (011.12) 3.
Конструкторы и деструкторы (010.2.3, 010.4.1) 4. Производные классы (глава 12, глава 15) 5. Виртуальные функции и абстрактные классы (012.2.6, 012.3) б. Режимы доступа раЬВс/ргогесгей/рг(гаге Я10.2.2, б! 5.3, ВС.!1) 7. Дружественные функции (911.5) 8. Указатели на члены классов 515.5, ВС.12) 9. Статические члены (010.2.4) 10. Ключевое слово «гигаЬ1е (010.2.7.2) 11. Перегрузка операций (глава 11) 12. Ссылки Я5.5) ° Средства, предназначенные в первую очередь для организации программ: 1.
Шаблоны (глава 13, ВС.13) 2. Встраиваемые функции (07.1.1); добавляются в С99 3. Аргументы по умолчанию (07.5) 4. Перегрузка функций (07.4) 1. 2. 3. 4. 5. б. 7. 8. 9. Комментарии // (92.3); добавляются в С99 Поддержка ограниченных наборов символов (ВС.3.1); частично добавляется в С99 Поддержка расширенных наборов символов (ВС.З.З); частично добавляется в С99 Неконстантные инициализаторы для объектов со статическим хранением (%9.4.1) соязг в константных выражениях 65.4, ВС.5) Объявления как операторы (96.3.1); добавляются в С99 Объявления в инициализаторах операторов/ог (86.3.3); добавляются в С99 Объявления в условиях (06.3.2.1) Имена структур не нужно предварять словом зггаст (05.7) Проверка типов аргументов функций (07.1); добавлено в С позже (ВВ.2.2) Безопасная по типам компоновка (09.2, 09.2.3) Выделение свободной памяти операциями яе» и ие1еге (06.2.6, 010.4.5, 015.6) соязт (05.4, 05,4.1); добавлено в С позже В.З.
Старые реализации Сч-+ 5. Пространства имен (88.2) б. Операция разрешения области видимости (операция::, 84.9.4) 7. Обработка исключений (88.3; глава 14) 8. Средства КТТ1 (815.4) Ключевые слова, добавленные в С++ (8В.2.2), можно использовать для идентификации большинства средств, специфичных для этого языка. В то же время„некоторые средства С++, такие как перегрузка функций или константы в константных выражениях, не идентифицируются по ключевым словам. Кроме перечисленных особенностей стандартная библиотека С++ (816.1.2) по большей части специфична именно для С-н-, Макрос ср!нзргнз применяется для того, чтобы выбрать компилятор С или С++ (89.2.4). В.З.
Старые реализации С++ Язык С++ интенсивно используется с 1983 года (81.4). С тех пор сменилось несколько его версий и множество независимо выполненных реализаций. Фундаментальная цель стандартизации языка заключалась в том, чтобы дать разработчикам реализаций и пользователям единое определение С++. В то же время, пока стандартное определение не распространится широко в среде программистов, придется смириться с неприятным фактом, что не каждая реализация поддерживает все средства, описанные в этой книге. К сожалению, часто люди, начинаюшие изучать язык С++, сталкиваются с реализациями пятилетней давности.