Совместима ли C99 с C89? - PullRequest
       24

Совместима ли C99 с C89?

15 голосов
/ 16 ноября 2009

Я привык к старому стилю C и только недавно начал изучать функции c99. У меня только один вопрос: удастся ли моей программе успешно скомпилироваться, если я использую в своей программе c99, флаг c99 с gcc и свяжу его с предыдущими библиотеками c99?

Итак, я должен придерживаться старого C89 или развиваться?

Ответы [ 8 ]

9 голосов
/ 16 ноября 2009

Я считаю, что они совместимы в этом отношении. Это до тех пор, пока материал, с которым вы компилируете, не наступит ни на один из новых вкусностей. Например, если старый код содержит enum bool { false, true };, у вас проблемы. Как подобный динозавр, я медленно обнимаю чудесный новый мир C99. В конце концов, он существует уже около 10 лет;)

7 голосов
/ 16 ноября 2009

Вы должны развиваться. Спасибо за прослушивание: -)

На самом деле я остановлюсь на этом.

Вы правы, что C99 существует уже довольно давно. Вы должны (по моему мнению) использовать этот стандарт для всего, кроме устаревшего кода (где вы просто исправляете ошибки, а не добавляете новые функции). Вероятно, это не стоит для унаследованного кода, но вы должны (как и во всех бизнес-решениях) провести собственный анализ затрат / выгод.

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

Что касается кода, на который следует обращать внимание, авторы стандартов серьезно относятся к обратной совместимости . Их работа никогда не заключалась в разработке нового языка, а в том, чтобы кодифицировать существующие практики.

Фаза, в которой они находятся в данный момент, дает им больше свободы в обновлении языка, но они по-прежнему следуют клятве Гиппократа с точки зрения своего вывода: «прежде всего, не навреди».

Как правило, если ваш код нарушен новым стандартом, компилятор вынужден сообщить вам об этом. Так что простая компиляция вашей базы кода будет отличным началом. Однако, если вы прочитаете документ C99 с обоснованием , вы увидите фразу «тихое изменение» - это то, что вам нужно остерегаться.

Это поведенческие изменения в компиляторе, о которых вам не нужно сообщать, и они могут стать источником сильного беспокойства и скрежета зубов, если ваше приложение начинает вести себя странно. Не беспокойтесь о битах «тихого изменения в c89» - если бы они были проблемой, они бы вас уже укусили.

Этот документ, кстати, отлично читается, чтобы понять, почему действительный стандарт говорит то, что он говорит.

2 голосов
/ 16 ноября 2009

Соглашения о вызовах между библиотеками C давно не менялись, и на самом деле, я не уверен, что это когда-либо изменилось.

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

Таким образом, в основном ответ таков: «Да, двоичные файлы будут обратно совместимы. Нет, естественно, код, использующий функции C99, не может быть позже скомпилирован компилятором, отличным от C99».

2 голосов
/ 16 ноября 2009

Если вы не нарушите явные функции C99, код c90 будет отлично работать с флагом c99 с другими предыдущими библиотеками c99.

Но в C89 есть некоторые библиотеки, основанные на DOS, например, которые, безусловно, не будут работать.

C99 очень гибкий, поэтому не стесняйтесь мигрировать: -)

2 голосов
/ 16 ноября 2009

С уважением: Попробуйте и узнайте. :-)

Тем не менее, имейте в виду, что даже если вам нужно исправить несколько небольших различий в компиляции, вероятно, стоит подняться вверх.

1 голос
/ 09 сентября 2016

Существует несколько частей стандарта C89, которые написаны неоднозначно, и в зависимости от того, как интерпретировать правило о типах указателей и объектах, к которым они обращаются, стандарт можно рассматривать как описание одного из двух очень разных языков - одна из которых семантически гораздо более мощная и, следовательно, может использоваться в более широком диапазоне областей, а одна из которых предоставляет больше возможностей для оптимизации на основе компилятора. Стандарт C99 «прояснил» правило, чтобы прояснить, что он не предпринимает никаких усилий для обеспечения совместимости с прежним языком, даже несмотря на то, что он был в подавляющем большинстве одобрен во многих областях; он также обрабатывает как неопределенные некоторые вещи, которые были определены в C89, но только потому, что правила C89 не были написаны достаточно точно, чтобы запретить их (например, использование memcpy для определения типа в случаях, когда у места назначения есть длительность кучи).

Таким образом, C99 может быть совместим с языком, который, по мнению его авторов, был описан C89, но не совместим с языком, который обрабатывался большинством компиляторов C89 в течение 1990-х годов.

1 голос

Некоторые функции C89 недействительны C99

Возможно, эти функции существуют только по историческим причинам и не должны использоваться в современном коде C89, но они существуют.

В стандартном черновике C99 N1256 * в предисловии 5, абзаце 5 сравнивается C99 со старыми ревизиями, и это хорошее место для начала поиска этих несовместимостей, даже несмотря на то, что он имеет гораздо больше расширений, чем ограничений.

Неявный int и типы переменных

Упоминается Лутцем в комментарии, например, Следующие действительны C89:

static i;
f() { return 1; }

но не C99, в котором вы должны написать:

static int i;
int f() { return 1; }

Это также исключает вызов функций без прототипов в C99: Требуются ли прототипы для всех функций в C89, C90 или C99?

n1256 говорит:

удалить неявный int

Возврат без выражения для не пустой функции

Действительный C89, недействительный C99:

int f() { return; }

Я думаю, что в C89 он возвращает значение, определенное реализацией. N1256 говорит:

возврат без выражения не разрешен в функции, которая возвращает значение

Целочисленное деление с отрицательным операндом

  • C89: округление в направлении, определяемом реализацией
  • C99: округляет до 0

Так что, если ваш компилятор округлился до -inf, и вы полагались на поведение, определенное реализацией, ваш компилятор теперь вынужден нарушать ваш код на C99.

https://stackoverflow.com/a/3604984/895245

n1256 говорит:

надежное целочисленное деление

Совместимость с Windows

Одной из основных практических проблем является возможность компиляции в Windows, поскольку Microsoft не намерена полностью внедрять C99 слишком рано .

Вот, например, почему libgit2 ограничивает допустимые возможности C99 .

1 голос
/ 16 ноября 2009

Он предназначен для обратной совместимости. Он формализует расширения, которые уже реализованы многими поставщиками. Возможно, даже возможно, что хорошо написанная программа не будет иметь проблем при компиляции с C99.

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

...