Comments 23

Хабр-торт! Прочитал на одном дыхании. Впечатляет, что столь древний код вполне можно собрать и запустить.

В этом сильно помогла стандартизация C. А вот можно ли будет сделать такое с любым новым системным языком без стандарта (Rust, Go, etc) — вопрос.

Так вроде как раз наоборот, первый стандарт C89 появился спустя только 2 года после выпуска первой версии Perl'а, о чём автор в статье упомянул:


Первый стандарт языка программирования «C», под названием «C89» появится лишь через два года.
По сути стандартизировали неформальный K&R, который был на тот момент, с учётом поправок, направленных на некоторые спорные моменты microsin.net/programming/arm/ansi-c-vs-kr-c.html. Поэтому такие ошибки в perl как модификация read-only строки, начиная с C89 уже не работали. Но и назвать их супер критичными, ломающими ABI и делающими невозможным компиляцию без полного переписывания кода тоже нельзя.

С совеременными языками ещё важный вопрос — это зависимости. Ведь их тоже надо будет через 30 лет взять именно тех версий, которые были на то время. И если используется современный тулчейн, то убеждать его в том, что использовать вот эту кучу устаревшего кода — это норм.


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

Да, проблема зависимостей для ныешнего языка играет куда более важную роль, чем стандарт. С другой стороны, есть софт который в идеале не должен зависеть от чего-либо внешнего, поэтому ломать сам язык тоже плохая идея. Да, к примеру у Go нет стандарта, поскольку реализация одна, но и нет обещания в виде формального стандарта, который гарантирует совместимость со старыми реализациями (не говоря уже про ABI, который и в Go, и в Rust привязан к C и при этом всё равно далеки от стабильных).

Стандарт сам по себе не гарантирует совместимость со старыми реализациями. Обратная совместимость — это опциональная возможность. Дизайнеры языка могут как закладывать её, так и нет.


У вас будут Индустральные Инженерные Стандарты™ на Go 1, Go 2… и даже на Go 14, только-только вышедший в 2054 году. Толку-то от этого, если компилятор не поддерживает всё, что ниже Go 12, потому что это никому не нужно в 50-х.

Да, стандарт может гарантировать, а может и нет. Но в случае C/C++ гарантии какие-никакие, но всё таки есть, и компиляторы, если хотят следовать стандарту, должны иметь обратную совместимость.
Да, к примеру у Go нет стандарта, поскольку реализация одна
Ещё есть gcc-go

Помню, что я без проблем собрал свой код на Паскале, 1998 года, написанный под DOS для Borland Pascal и использующий массу библиотек тех лет (Turbo Vision и прочие сторонние штуки, неизвестно откуда взявшиеся) уже с помощью Free Pascal и под Linux. Чисто своего кода было под 600 килобайт, если верно помню и портировать его было во много раз легче, таких плясок не было. Конечно, это заслуга Free Pascal Team, не такой большой разницы в годах, ну и тем, что Паскаль более высокоуровневый (хотя там и asm вставки были и работа с видеопамятью напрямую и т.п., но это элементарно я поправил еще в те годы, когда решил это с DOS переносить на другие платформы).

Может быть когда-нибудь какой-нибудь цифровой археолог наткнётся на эту статью и она ему будет полезна. Но в реальном мире даже опыт, извлечённый из подобных изысканий, по моему мнению, не слишком уж ценен.
Эта статья и есть цифровая археологическая экспедиция.
патчи (попали в PRs)

Всё таки в Pull request'ах там лишь те PR (всего несколько десятков штук), которые люди открывали, когда репозиторий был просто зеркалом. В большинстве из них — комментарии вида "мы не работаем с PR, используйте perlbug".

Боюсь, он найдёт там over9000 ошибок, являющиеся ошибками для современных компиляторов и стандарта языка «C», но вполне допустимыми конструкциями в не стандартизированном 32-х летнем коде.

Ну, учитывая, что Cfront им в своё время проверить, пусть и не без шаманства, всё-таки удалось...

Спасибо за статью! Теперь интересно увидеть результаты сканирования PVS-Studio
В парочке мест были определены статические функции без объявлений. Компиляторы со временем стали строже относиться к этой проблеме и превратили предупреждение в ошибку.

Это точно не перевод? Судя по ссылке, компиляторы превратили в ошибку расхождение сигнатуры в объявлении и определении, а вовсе не отсутствие первого.

Нет, это не перевод. Компилятор при отсутствии объявления ругается следующим образом:


malloc.c:153:1: error: static declaration of ‘morecore’ follows non-static declaration
malloc.c:124:5: note: previous implicit declaration of ‘morecore’ was here
  124 |     morecore(bucket);
      |     ^~~~~~~~

Я не слишком вникал в эту проблему, но кажется отсутствие явного объявления статической функции является частным случаем расхождения сигнатуры. Возможно привёл не слишком удачную ссылку на Stack Overflow.


В любом случае, спасибо за замечание!

Просто, насколько я понял, если объявления нет, компилятор неявно создаёт его сам, но в этом случае, поскольку он не знает, статическая функция или нет, он делает функцию не статической. А потом встречается определение…

mktemp() пытается поменять литерал по маске, который находится в секции .rodata, что заведомо обречено на провал. Или всё-таки 32 года назад подобное было допустимо, встречалось в коде и даже как-то работало?

В то время в elf-файлах могло не быть секции rodata, а ещё, помнится, в Турбо-Паскале 6.0 был разговор о том что можно изменить переменную с предустановленным значением. Если переменная была объявлена как, скажем, var i:integer=1; потом спокойно допускалось i:=2; и для строк такое тоже проходило. В этом месте литерал не объявлен константой вообще, поэтому по умолчанию размещался в перезаписываемой области данных.

Only those users with full accounts are able to leave comments. Log in, please.