Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 203
Текст из файла (страница 203)
Введение В этом приложении обсуждаются несовместимости между С н С++, а также между станлартом С++ и более ранними версиями языка С++. Цель данной главы — документировать различия, которые могут вызвать проблемы у программиста, и указать пути их преодоления. Большинство проблем с совместимостью возникает: когда кто-то пытается обновить программу на С, чтобы сделать ее программой на С+а, прн попытках перенести написанную на С-н- программу с одной нестандартной версии С~-~ на другую и при попытках скомпилировать программу с новейшими особенностями языка на старом компиляторе. Моя цель — не утопить вас в деталях кюкдой проблемы совместимости, когда-либо возникавшей в какой-либо реализации, а просто перечислить наиболее часто встречавлпиеся трудности и представить стандартные решения. При анализе вопросов совместимости очень важно рассмотреть диапазон реалпзщпгй, в которых программа должна работать.
Для изучения С~-~ имеет смысл использовать наиболее полную и удобную реализацию. Для конечного продукта правильной является более консервативная стратегия, призванная максимально расширить число систем, в которых этот продукт сможет работать. В прошлом это служило оправданием бегства от новпгеств С--». Однако реапизацин сближаются, и необходимость переносимости с одной системы на другую теперь не требует той чрезвычайной осторожности, как пару лет назад.
Б.2. Совместимость С/С++ За минимальными исключениями С++ является надмножеством С. Наиболее значительные различия возникают иэ-за большей строгости С++ при проверке типов. Хорошо написанные программы на С как правило оказываются и программами на С<-~. Все различия между Сее и С может выявить комшщятор. Б.2.1. «Тихие» различия За немногими исключениями, программы, являющиеся программами и на С, и на С++, имеют в обоих языках один~новый смысл. К счастью, эти исключения («тихие» различия) сравнительно незначительны: 892 Приложение Б. Совместимость В С размер символьной константы и перечисления равны в(яеот (1п1).
В С+ь в)хвое'и') равно в(хеоД(сЬш), и реализациям С+ж разрешено выбирать размер, лучше всего подходящий для перечисления (9 4.8). С++ использует для комментариев знак //; С не позволяет этого (хотя многие реализации С тоже допускают такой комментарий в качестве расширения языка).
Это различие можно использовать, чтобы конструировать програмльы, ведущие себя на разных языках по-разному. Например; 1пГ/(1пга, тГЬ) ( гв1игп а // * довольно невероятна */0 , /* нереалиспшчно: спичка с запнтаи в отдельной строке во избежание синтаксической о~иибки */ л 8 О С (международный стандарт С) пересматривается, чтобы ввести комментарии // в С, Имя структуры, объявленное во внутренней области видимости, может скрыть имя объекта, функции, перечисления или типа во внешней области видимости. Например: 1псх(УУ), ва!дЩ) в1гис1 х (! пГ а; ); в1хеоДх); //рвал~ар лсассива на С, рпзльвр структурьь на С++ Б.2.2. Код на С, не являющийся кодом на С++ Несовместимости С/С++, вызывающие большинство реальных проблем, не очень изощренны.
Многие из них легко вылавливаются компиляторами. В данном разделе приведены примеры кода на С, который не является допустимым кодом на С++. Многие из них для современного С считаются дурным тоном или даже устаревшигии. На С большинство функций можно вызывать без предварительного обьявления: талл () /* дурной тон в С. Не Сл-ь */ ( даиЫе вд2 = вуг1 (2); /* вызов необъявленной дэунклии '/ рг1п(Якорень из 2равен7уэп,вд2); /* вызов необълвленнайдэункщса*/ Полное и последовательное использование объявлений (прототипов) функций, вообще говоря, рекомендуется и для С. Там, где этому разумному совету следуют, н особенно там, где компилятор С предоставляет опции обязательного объявления, программа на С соблюдает правила С++. Там, где вызываются необъявленные функции, вам нужно довольно хорошо знать функции и правила С, чтобы понять, где вы сделали ошибку нли породили проблему, связанную с переносимостью.
Например, приведенная выше функция та(п () как программа на С++ содержит по крайней мере две ошибки. В языке С функция, объявленная без описания типов аргумента, может принимать любое число аргументов любого типа. Подобное использование признано в Стандарте С устаревшим, но оно встречается: /" типы аргумента не упонинанэтся */ иоиЦ'(); 893 Б.2.2.
Код на С, не являющийся кодом на С++ иоЫу() ( Д2); /* дурной тон в С. Ие С'+ */ В С функции можно определять с использованием синтаксиса, который (не обязательно) описывает типы аргументов после перечня аргументов; иоиЦ(а, р, с) сйаг' р, сйагс; (/"., "/) /'С, не Сн-*/ Такие определения надо переписать: иоЫ) (гп1а, сдпг'р, гааге) (/*. В С н старых версиях С++, предшествовавших стандарту, специфнкатором типа по умолчанию считается Ы1.
Например: сипв1 а = 7 /*)3 С подразунееиется тип )п1. Не С++ '/ Стандарт! ВО С пересматривается, чтобы тоже не допускать «неявного 1п1ж как и в С+я. С допускает определения структур в возвращаемом типе и в объявлении типа аргумента. Например: /*С, нсС««'/ /" С, не С«« */ вггис1 5 ( Ы1х, у; ) Д); иоЫд(вггис15 [)п1х, у; ) у); Правила С++ определения типа делают такие объявления бесполезными и не допускают их. В С переменным типа перечислений можно присваивать целые числа: спит Рягессюп ( ир, с(отп ); спит 1«ггес11оп с( = 1, /*ошибка: т1 присвииваепсл 0йесйоп; в С вЂ” допусти по */ В С++ гораздо больше ключевых слов, чем в С.
Если какое-нибудь нз них появится в программе на С как идентификатор, эту програмяиу нужно будет переделать для совместимости с С++. Ключевые слова С++, которые не являются ключевыми словами С В С некоторые из ключевых слов С++ являются макросами, определенными в стан- дартных заголовочных файлах: Ключевые слова С++, являющиеся макросами на С Ь!1апг( Ы1ог алс( ап«1 еу сотр1 по1 по1 ед ог ог ед шсйаг 1 хог хог ед аяЫ аМ ед авт Ь11апс( Ыуог Ьоо( са1сй с1авв сотр1 сопв1 сав1 с(е(е(е Иупат(с сав1 ехр1)с)1 ехрог1 /а(ве /г)ела )пупе ти(аЫе патеврасе пеи ло1 по1 еу орега1ог. ог ог ед рыла 1е рго1ес1ес( риЫсс ге)п1егрге1 сав1 в1а11с сав1 1етр1а1е 1Ь!в 1Ьгош 1 ае 1гу 1уреЫ 1урепате ив)я~у о(г1иа1 шсйаг 1 хог еу 894 Приложение Б.
Совместимость Это подразумевает, что в С они могут проверяться при помощи !С(/с(е/; замешаться и т. п. В языке С глобальные объекты данных можно объявлять в одной единице трансляции несколько раз без спецификатора ех!егп. Если инициализатор встречается только в одном из таких объявлений, объект считается определенным лишь один раз.
Например: тгй и!й /* определяет или объявляет одну иелую переменную !; не С++ */ В С++ переменная должна быть определена ровно один раз; 9 9.2,3. В С++ класс не может иметь то же имя, что и имя, определенное при помощи !урес(е~ для обозначения другого типа в той же области видимости; 9 5Д. В С воЫ' можно использовать в качестве правого операнда в присваивании или при инициализации переменной любого указательного типа; в С++ этого делать нельзя (9 5.6). Например; о оЫ/(!и!.и( ( !пс» р = таПос (п*в!еео/~!пй(; /'не С++ Виделяйяе палить в С++ при помои(и нею "/ Язык С разрешает переходы (уо!о) в обход инициализации; С++ не разрешает.
В С имена вложенных структур размещаются в той же области видимости, что и структура, в которую они вложены. Например: в!гис! В ( в!гас! Т ( /* ... */ //" ); /* В С правильно и означаеьп: Внтх, Ое С++ */ в!гас! Тх, В С массив может инициализироваться инициализатором, в котором элементов больше, чем требуется для этого массива. Например: сйаг о(б) = "Оскар"; /' Допустимо в С, завершаюи(ий сщюяу О не используепюя.
!!е С н-*/ 5.2.3. Нежелательные особенности Используя термин «нежелательные особенности», комитет по стандарту выражает пожелание эти особенности убрать. Однако у комитета нет права удалять широко используемые свойства — как бы избыточны и опасны они не были. Таким образом. нежелательность является для пользователей всего лип!ь настоятельным советом избегать этих особенностей.
Ключевым словом з!а!!с, обычно означающим «статически распределяемый», можно воспользоваться как индикатором, что функция или объект локальны для данной единицы трансляции. Например: 0файл! в!а!!с !и! у!оЬ; //файл2 всайс!пгу!оЬ; Эта программа на самом деле имеет две целочисленных переменных с именем фоЬ. Каждая в1оЬ используется исключительно функциями, определенными в ее единице трансляции. 895 Б.2. Совместимость С/С++ Использование я1а11с для индикации «локальная для единицы трансляцпиь в С++ нежелательно. Вместо этого пользуйтесь неименованными пространствами имен (9 8.2.5.1).
Неявное преобразование строкового литерала в (неконстантный) сйпг* нежелательно. Используйте именованые массивы сйагили избегайте присваивания строковых литералов переменным типа ейная (6 5.2 2). Приведения типа в стиле С тоже стали нежелательны после введения приведений в новом стиле. Программисты должны серьезно подумать над запрещением приведения в стиле С в своих программах. Там где необходимо явное преобразование, то же самое могут сделать з1а11с саз1, гет1егрге1 саИ, солИ сая1 нлн их сочетания. Следует предпочитать приведения типа в новом стиле, так как они более явные, и их лучше видно (6 6.2.7). Б.2.4.