Си: жёсткий разбор

Язык Си отличается богатым набором средств, которые способны сломать программу в самых разных местах и самым неочевидным способом.

Это всевозможные побитовые операции и неочевидные реализации некоторых типов (например, процессор не умеет работать с 32-разрядными целыми, и что будет в результате их сдвига, надо выяснять экспериментально); преобразование целых и дробных друга в друга неоднозначными и нагрузочными действиями; небезопасные строки с нулём в конце; возможность использования целых чисел в качестве значений указателей; и так далее…

Полное отсутствие средств контроля переполнения буфера — этим багам посвящено огромное количество баек, причём последствия нередко бывают очень серьёзными.

Синтаксис? Достаточно вспомнить классический баг с перепутыванием = и ==, или отсутствие обязательного else/default в операторе выбора. А уж как любят си-программисты хвастаться компактной записью кода, особенно если в ней задействованы указатели, когда любая опечатка приведёт к потенциальному краху всей программы, причём возможно не сразу, а через месяц успешной работы.

Деплой? Кто часами возился с линковкой статических библиотек, настройками make и подключением внешних dll-ек, наверняка вспоминает о развёртывании с ужасом. А уж кривые настройки сотен препроцессорных директив способны украсть на пустом месте десятки часов работы.

Си любят называть «переносимым ассемблером», однако наиболее важные характеристики ассемблера в Си как раз отсутствуют. Например, нету нелокальных переходов, а стек сокрыт, что мешает реализовывать эксепшены, трассировщики, сборки мусора. Более того, хорошие макро-ассемблеры позволяют строить весьма гибкие управляющие конструкции, в Си же они просто встроены в язык в ограниченном виде. А так как нельзя манипулировать скомпилированным кодом напрямую, нам не сделать качественный бут-загрузчик. Также, выравнивания и преобразования вызовов всегда неявны, в отличие от тру-ассемблера.
Си — это такой полусырой «низкоуровневый» язык, сильно проигрывающий любому макро-ассемблеру. Если пишется системный код — то, очевидно, для конкретной платформы. Тогда выгода с переносимостью Си пропадает, и гораздо лучше сразу брать ассемблер. А если уж нужна кросс-платформность, лучше уж брать Фортран, который обыгрывает Си по всем пунктам.

К сожалению, людей сегодня учат программировать на си-подобных языках, так как мэйнстрим готов им хорошо платить — по историческим причинам, связанным прежде всего с ограниченностью и недальновидностью ИТ-менеджеров. В результате, люди испытывают множество проблем в понимании действительно сильных идей, от функционального программирования и рефлексии до метапрограммирования и гомоиконичности. Более того, проблемы есть и в непонимании того, что человеку присущи упомянутые проблемы с пониманием правильных вещей.

Поделиться статьей ...Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Share on VKPrint this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *