В Stack Overflow есть очень опытные люди, которые всегда говорят о стандарте C. Людям, похоже, не нравятся непереносимые решения, даже если они работают на меня. Хорошо, я понимаю, что стандарт должен соблюдаться, но разве он не мешает творчеству программиста?
Каковы конкретные преимущества, которые дает соблюдение стандарта? Тем более что компиляторы могут реализовывать стандарт немного по-другому.
programming-languages
c
standards
0decimal0
источник
источник
Ответы:
Есть несколько причин, почему придерживаться стандарта - это хорошо.
Быть заблокированным в компиляторе - отстой. Вы полностью во власти группы разработчиков с их собственной повесткой дня. Они явно не хотят вас или чего-то еще, но если ваш компилятор начинает отставать от оптимизаций, новых функций, исправлений безопасности и т. Д., Слишком плохо; Вы застряли. В некоторых случаях некоторым компаниям приходится исправлять любой инструмент, от которого они сами зависят. Это огромная трата денег и времени, когда есть другие рабочие инструменты.
Быть запертым на платформе - отстой. Если вы продвигаете программное обеспечение для Linux и хотите переключиться на Windows, потому что понимаете, что ваш рынок действительно существует, вам понадобится немало времени, чтобы изменить каждый непереносимый хак, который у вас есть в коде, для хорошей игры. как с GCC, так и с MSVC. Если у вас есть несколько частей вашего основного дизайна, основанного на чем-то подобном, удачи!
Обратно несовместимые изменения сосет тяжелее всего. Стандарт никогда не нарушит ваш код (игнорировать python). Некоторые случайные авторы компиляторов могут решить, что на самом деле это дополнение для конкретной реализации не стоит проблем, и отбросить его. Если вам случится положиться на него, то вы застряли на любой старой версии, в которой она была последней.
Таким образом, главное сообщение, придерживающееся стандарта, делает вас более гибким . У вас конечно более ограниченный язык, но у вас больше
Это тонкий баланс, но полное игнорирование стандарта определенно является ошибкой. Я склонен организовывать свой C-код, чтобы полагаться на абстракции, которые могут быть реализованы непереносимым способом, но которые я могу прозрачно портировать, не меняя все, что зависит от абстракции.
источник
Стандарт является своего рода «контрактом» между вами и вашим компилятором, который определяет значение ваших программ. Как программисты, мы часто имеем определенную ментальную модель того, как работает язык, и эта ментальная модель часто расходится со стандартом. (Например, программисты на C часто думают об указателе как о «целом числе, обозначающем адрес памяти», и поэтому предполагают, что безопасно выполнять любые арифметические операции / преобразования / манипуляции с указателями, которые можно выполнить с целым числом, обозначающим память адрес. Это предположение не соответствует стандарту, оно налагает очень строгие ограничения на то, что вы можете делать с указателями.)
Итак, в чем преимущество следования стандарту, а не вашей собственной ментальной модели?
Проще говоря, это то, что стандарт верен, а ваша собственная ментальная модель неправильна. Ваша ментальная модель, как правило, представляет собой упрощенное представление о том, как все работает в вашей собственной системе, в общих случаях, когда все оптимизации компилятора отключены; Поставщики компиляторов, как правило, не прилагают усилий, чтобы соответствовать ему, особенно когда речь идет об оптимизации. (Если вы не задерживаете конец контракта, вы не можете ожидать какого-либо особого поведения от компилятора: мусор входит, мусор выходит.)
Может быть, лучше сказать, «даже если они, кажется, работают на меня». Если ваш компилятор специально не документирует, что данное поведение будет работать (то есть: если вы не используете обогащенный стандарт, состоящий из собственно стандарта плюс документация компилятора), вы не знаете, что он действительно работает или что он действительно надежен. Например, целочисленное переполнение со знаком обычно приводит к переносу во многих системах (так,
INT_MAX+1
как правило , естьINT_MIN
), за исключением того, что компиляторы «знают», что целочисленная арифметика со знаком никогда не переполняется в (правильной) программе на C, и часто выполняют очень неожиданные оптимизации на основе этого » знание".источник
-fwrapv
, и тогда вы используете немного другой, нестандартный язык, в который всегда входит целочисленная арифметика со знаком.Нет. Стандарт сообщает, что разрешено делать. Если он не указан, вы находитесь на неопределенной территории поведения, и тогда все ставки отключены - программа может делать все что угодно.
Поскольку вы упомянули конкретный пример
void main()
противint main()
, я могу улучшить свой ответ.void main()
не является стандартным объявлением основной функции. Он может работать на некоторых компиляторах через расширения, но зависит от реализации. Даже если это работает, вы должны проверить, делает ли это то, что вы хотите. Проблема в том, что разработчики компиляторов могут решить удалитьvoid main()
следующем выпуске компилятора, что нарушит работу вашего приложения.С другой стороны, стандарт четко определяет сигнатуру main
int main()
и указывает, что он должен делать.С другой стороны, есть вещи, которые не определены в стандарте. Затем может применяться другой стандарт (например, POSIX). Лучший пример может быть с реализацией потоков в c ++ 03, поскольку стандартные программы c ++ 03 были однопоточными. В этом случае вы вынуждены использовать библиотеку, зависящую от платформы, или что-то вроде boost .
источник
Не следуйте правилам, если ваш проект касается специальных проектов, например, правительственного или армейского, но вы должны следовать правилам, если вы говорите о проекте с открытым исходным кодом или большом проекте с распределенной командой.
источник