В большинстве случаев более поздние версии являются надмножествами более ранних версий. В то время как код C89, который пытается использовать restrict
в качестве идентификатора, будет разбит на добавление C99 зарезервированного слова с тем же правописанием, и, хотя есть ситуации, в которых код, который умудрился использовать некоторые угловые случаи с парсером, будет обрабатываться по-разному на двух языках большинство из них вряд ли будут важны.
Более важная проблема, однако, связана с псевдонимом памяти. C89 включают в себя правила , которые ограничивают типы указателей, которые могут использоваться для доступа к определенным объектам . Поскольку правила сделали бы такие функции, как malloc() бесполезными, если они применили, как написано, к созданным им объектам, большинство программистов и писатели-компиляторы рассматривали правила как применяющие только в ограниченных случаях (я сомневаюсь, что C89 был бы широко принято, если люди не считают, что правила применяются только узко). C99 утверждал, что «разъясняет» правила, но его новые правила гораздо более экспансивны по сравнению с одновременными интерпретациями старых, нарушая много кода, который бы определял поведение в рамках общих интерпретаций C89, и даже некоторый код, который было бы однозначно определено в разделе C89, не имеющем практического эквивалента C99.
В C89, например, memcpy
может использоваться для копирования битового шаблона, связанного с объектом любого типа, с объектом любого другого типа с одинаковым размером, в любом случае, когда этот бит-шаблон будет представлять допустимое значение в типе назначения. C99 добавил язык, который позволяет компиляторам вести себя произвольно, если memcpy
используется для копирования объекта некоторого типа T в хранилище без объявленного типа (например,хранилище, возвращаемое с malloc
), и это хранилище затем считывается как объект типа, который не является псевдонимом, совместимым с T, даже если бит-шаблон исходного объекта будет иметь действительное значение в новом типе. Кроме того, правила, применимые к memcpy, также применяются в случаях, когда объект копируется как массив типа символа - без каких-либо уточнений, что это значит, - поэтому неясно, какой именно код нужно будет сделать для достижения поведения, соответствующего C89 memcpy
.
Во многих компиляторах такие проблемы могут быть решены путем добавления в командной строке опции -fno-strict-aliasing
. Обратите внимание, что указание режима C89 может быть , но не, поскольку авторы-компиляторы часто используют одну и ту же семантику памяти независимо от того, какой стандарт они должны выполнять.
Вы продолжаете говорить ISO C, но я думаю, вы имеете в виду ANSI C (или C89 или C90, все три из этих имен относятся к одному и тому же языку). ISO C сам по себе ничего не значит (и важно отметить, что как C99, так и C11 определяются органами языка ISO). – Cornstalks
@Cornstalks Технически каждый стандарт ISO C заменяет своих предшественников, и ANSI использует стандарты языка ISO C, поэтому «ANSI C» будет означать также C11. (Но большинство людей этого не используют). – melpomene
https://github.com/mauke/poly.poly/blob/master/poly.poly может различать C89 и C99 (путем компиляции с разными семантиками в каждом) , поэтому ответ на Q1 «нет». – melpomene