Совместим ли C99 с C89?
Я привык к старому стилю C и недавно начал изучать функции c99. У меня только один вопрос: успешно ли будет скомпилирована моя программа, если я использую c99 в моей программе, флаг c99 с gcc
и свяжу ее с предыдущими библиотеками c99?
Итак, должен ли я придерживаться старого C89 или развиваться?
Ответы
Ответ 1
Я считаю, что они совместимы в этом отношении. Это до тех пор, пока материал, который вы компилируете, не наступает ни на один из новых лакомств. Например, если старый код содержит enum bool { false, true };
, то у вас проблемы. Как подобный динозавр, я медленно обнимаю замечательный новый мир C99. В конце концов, он был только там, скрываясь около 10 лет;)
Ответ 2
Вы должны развиваться. Спасибо за прослушивание: -)
Собственно, я расширю это.
Вы правы, что C99 существует довольно давно. Вы должны (по-моему) использовать этот стандарт для чего-либо иного, кроме старого кода (где вы просто исправляете ошибки, а не добавляете новые функции). Вероятно, это не стоит для устаревшего кода, но вы должны (как и во всех бизнес-решениях) делать свой собственный анализ затрат/выгод.
Я уже гарантирую, что мой новый код совместим с C1x - пока я еще не использую какие-либо новые функции, я стараюсь, чтобы он не сломался.
Что касается кода, на который следует обратить внимание, авторы стандартов очень серьезно относятся к обратной совместимости. Их работа не заключалась в разработке нового языка, это было кодирование существующих практик.
Фаза, в которой они сейчас находятся, позволяет им еще больше свободы в обновлении языка, но они по-прежнему следуют клятве Гиппократа с точки зрения выхода: "в первую очередь, не навреди".
Как правило, если ваш код разбит на новый стандарт, компилятор вынужден вам сказать. Так что просто компиляция базы кода будет отличным началом. Однако, если вы читаете документ с обоснованием C99, вы увидите выражение "тихая замена" - это то, что вам нужно следить за.
Это поведенческие изменения в компиляторе, о которых вам не нужно сообщать, и может быть источником сильной тоски и скрежещения зубов, если ваше приложение начинает действовать странно. Не беспокойтесь о "тихих изменениях в c89" битах - если бы они были problerm, вы бы уже были укушены ими.
Этот документ, кстати, отлично читается, чтобы понять, почему настоящий стандарт говорит, что он говорит.
Ответ 3
С уважением: Попробуйте и узнайте.:-)
Хотя, имейте в виду, что даже если вам нужно исправить несколько небольших компиляционных различий, перемещение вверх, вероятно, стоит того.
Ответ 4
Если вы не нарушаете явные функции C99, код c90 будет работать с точным флагом c99 с другими предыдущими библиотеками c99.
Но в C89 есть несколько библиотек на основе dos, которые, безусловно, не сработают.
C99 очень гибкий, поэтому не стесняйтесь мигрировать: -)
Ответ 5
Вызывающие соглашения между библиотеками C не изменились в возрасте, и на самом деле я не уверен, что он когда-либо был.
Операционные системы в этот момент в значительной степени зависят от конвенций C-вызова, поскольку API-интерфейсы C обычно являются клеем между частями ОС.
Итак, в основном ответ: "Да, двоичные файлы будут обратно совместимы. Нет, естественно, код с использованием функций C99 не может быть позже скомпилирован с помощью компилятора, отличного от C99".
Ответ 6
Он предназначен для обратной совместимости. Он формализует расширения, которые уже реализованы многими вендорами. Возможно, возможно, даже возможно, что хорошо написанная программа не будет иметь проблем при компиляции с C99.
По моему опыту, перекомпиляция некоторых модулей, а не других, чтобы сэкономить время... тратит много времени. Обычно есть некоторые легко забытые детали, которые нуждаются в новом компиляторе, чтобы сделать его совместимым.
Ответ 7
Некоторые функции C89 недействительны C99
Возможно, эти функции существуют только по историческим причинам и не должны использоваться в современном коде C89, но они существуют.
Стандартная версия C99 N1256 в предисловии к параграфу 5 сравнивает C99 с более старыми версиями и является хорошим местом для начала поиска этих несовместимостей, даже хотя он имеет гораздо больше расширений, чем ограничения.
Неявные int return и типы переменных
Упоминается Лутцем в комментарии, например. действительны 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 говорит:
return без выражения, не разрешенного в функции, которая возвращает значение
Целочисленное деление с отрицательным операндом
- C89: раунды до определенного направления реализации
- C99: раунды до 0
Итак, если ваш компилятор округлен до -inf
, и вы полагаетесь на это поведение, определенное определением, ваш компилятор теперь вынужден сломать ваш код на C99.
fooobar.com/questions/3101/...
n1256 говорит:
надежное целочисленное деление
Совместимость с Windows
Одной из основных практических задач является возможность компиляции в Windows, поскольку Microsoft не намерена полностью внедрять C99.
Это, например, почему libgit2 лимиты позволили использовать функции C99.
Ответ 8
Существует несколько частей стандарта C89, которые неоднозначно написаны, и в зависимости от того, как интерпретировать правило о типах указателей и объектах, к которым они обращаются, стандарт можно рассматривать как описание одного из двух очень разных языков - один из которых семантически гораздо более мощный и, следовательно, применим в более широком диапазоне полей, и один из них позволяет больше возможностей для оптимизации на основе компилятора. Стандарт C99 "разъяснил" правило, чтобы четко указать, что он не прилагает никаких усилий для обеспечения совместимости с прежним языком, хотя он был подавляющим большинством голосов во многих областях; он также рассматривает как undefined некоторые вещи, которые были определены в C89, но только потому, что правила C89 не были написаны достаточно точно, чтобы запретить их (например, использование memcpy
для записи типа в случаях, когда место назначения имеет продолжительность кучи).
C99 может, таким образом, быть совместимым с языком, который, по мнению авторов, был описан C89, но не совместим с языком, который был обработан большинством компиляторов C89 в течение 1990-х годов.