Проект curl основан на фундаменте, заложенном в конце 1996 года инструментом под названием httpget.

ANSI C, ставший известным как C89


В 1996 году было не так много хороших альтернатив для создания небольшого и эффективного инструмента командной строки для передачи данных через Интернет. Я не хочу сказать, что C был единственным имевшимся языком, но для меня выбор был прост, и, честно говоря, когда начался этот путь, я даже не думал о каких-то других языках. Мы называли версию этого языка ANSI C, чтобы отличать его от «старорежимного» C K&R. Версию ANSI C позже переименовали в C89 (иногда её называют C90, и это сбивает с толку).

В 2000 году мы выпустили libcurl — библиотеку, предоставляющую всем желающим суперсилы передачи данных через Интернет. Это ещё сильнее оправдывало выбор C. Благодаря C мы могли без проблем предоставить стабильный API/ABI, чего в то время не мог обеспечить даже C++. К тому же это был достаточно портируемый язык, поэтому мы смогли перенести curl и libcurl практически на все современные операционные системы.

Поскольку я хотел, чтобы curl и libcurl предоставляли возможности системного уровня, и нацеливался на максимально широкое распространение, их нельзя было написать ни на одном из высокоуровневых языков наподобие Perl, Python или им подобных. Из-за этого они стали бы слишком большими и тащили за собой слишком много «лишнего багажа».

Я убеждён, что использование (консервативного) C для разработки curl — ключевой фактор его успеха и возможности использования его «где угодно».

C99


Стандарт C99 был опубликован (сюрприз!) в 1999 году, однако его освоение компиляторами заняло долгое время, что мешало нам его использовать. Мы хотели, чтобы curl был доступен «повсюду», поэтому пока одни из самых популярных компиляторов не поддерживают C99, мы даже не рассматривали возможность смены версии C, поскольку это могло бы подвергнуть риску распространение и использование curl.

Позже всех из популярных компиляторов освоил C99 компилятор Microsoft Visual C++, который реализовал этот стандарт должным образом только в 2015 году, а в 2019 году улучшил его поддержку. Большое количество наших пользователей/разработчиков по-прежнему придерживалось старых версий MSVC, поэтому не все пользователи этого пакета могут собирать программы на C99 даже сегодня, в конце 2022 года.

C11, C17 и дальше


Тем временем, ISO C Working Group продолжает выдавать обновления языка C. Был выпущен C11, появился C17, а теперь они работают над находящейся в рассмотрении версией C2x, которую, предположительно, назовут C23.

Повысить требования для curl?


Мы понимаем, что другие популярные проекты на языке C движутся вперёд, подняв свои требования до версии C99 или выше. Среди них ядро Linux, проект git и многие другие.

Обсуждение повышения версии C происходило и в рассылке libcurl, в частности, мы уже запланировали выпуск версии 8 весной 2023 года, поэтому теоретически это мог бы быть подходящий момент для внесения подобных изменений.

Какие возможности C99 могут улучшить проект наподобие curl? Самые интересные части C99, которые могут повлиять на код curl, на мой взгляд, следующие:

  • Комментарии //
  • Стандартный идентификатор __func__
  • Булевый тип в <stdbool.h>
  • Специальные инициализаторы struct
  • Пустые аргументы макросов
  • Расширенные типы integer в <inttypes.h> и <stdint.h>
  • Динамические члены массивов (массивы нулевого размера)
  • inline-функции
  • Правила типов целочисленных констант
  • Смешанные объявления и код
  • Тип long long и библиотечные функции
  • Семейство функций snprintf()
  • Допустимая висячая запятая в объявлении enum
  • Макросы vararg
  • Массивы переменной длины

То есть да, мы можем использовать множество крутых штук. Но действительно ли они нам нужны?

Для многих из представленных выше возможностей у нас уже есть достойные и функциональные замены. Многие из возможностей для нас не важны. Остальные могут просто отвлекать нас от дела.

При безусловном использовании C99 в коде curl возникает угроза того, что люди начнут переписывать разные части инструмента, поэтому нам пришлось двигаться аккуратно и открывать доступ к новым возможностям C99 постепенно. Именно так же поступает и проект git. Сложность такого подхода в том, что сложно проверить соответствие допустимых и используемых возможностей, поскольку у существующего инструментария обычно нет такой функциональности.

Также задавался вопрос: если мы рассматриваем возможность повышения требований, то не стоит ли нам поднять их до C11, а не останавливаться на C99?

Не сейчас


В конечном итоге, ни один человек пока так и не смог чётко донести, какие преимущества такое повышение требований к версии C даст проекту curl. В основном мы видим риск в том, что окажемся затянутыми в довольно несущественные обсуждения, и что изменения не особо продвинут проект вперёд как с точки зрения возможностей, так и качества/безопасности.

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

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

Умеренные изменения в требованиях


Мы решили, что начиная с curl 8 будем требовать, чтобы компилятор поддерживал 64-битный тип данных. Его не существовало в исходной версии C89, он был добавлен в C99. Однако уже не осталось современных компиляторов, не поддерживающих его.

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

Возможно, именно так мы продолжим адаптироваться и в дальнейшем использовать отдельные возможности, появившиеся после C89: выбирая их одну за другой и постепенно адаптируя их.

Мы отказались от C99 не навсегда


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

Другие языки


Мы не рассматриваем возможность перехода или переписывания curl на какой-то другой язык.

Комментарии (19)


  1. v1000
    22.11.2022 09:25
    +3

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

    почему-то напомнило историю, когда Эппл взяла и отказалась от поддержки 32 битных приложений. причем настолько, что даже убрала их из магазина приложений. то, что такие приложения устарели, но все ещё работали, и, зачастую, так и не были обновлены разработчиками для поддержки 64 бит, их не волновало.


    1. charypopper
      22.11.2022 10:56
      +1

      Это отличие между энтузиастами, ставившими ux во главу угла, и капиталистами максимизирующими прибыль


      1. 0xd34df00d
        22.11.2022 20:03
        +2

        Ложная дихотомия.


        Я в своём проекте (личном, на энтузиазме) в своё время очень быстро переходил на новые стандарты C++. Иногда — ещё до того, как релизились компиляторы с их поддержкой.


  1. anzay911
    22.11.2022 10:10
    +1

    Когда кто-то напишет какой-нибудь xurl на новом стандарте или даже языке, и он станет более популярным, чем curl, вопрос закроется сам собой.


    1. Envek
      22.11.2022 10:44
      +1

      Так уже есть httpie — на питончике написанный, у него очень приятный UI, с кучей плагинов к тому же. Например, только с помощью стороннего плагина к нему (и немного багфиксинга) я смог сделать хитрую подпись multipart-запросов на AWS — никто больше не умел, ни curl, ни postman.


      1. Stanislavvv
        22.11.2022 13:32
        +1

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


        1. snp
          22.11.2022 15:49
          +1

          Может быть, подойдёт такой вариант?


          % nix bundle nixpkgs#httpie
          % ls -lHh httpie
          -r-xr-xr-x 2 root root 70M Jan  1  1970 httpie
          % ./httpie --version
          3.2.1

          Для запуска нужно лишь работающий /bin/sh и ничего более.


          1. Stanislavvv
            22.11.2022 16:09

            Вероятно, подойдёт. Особенно, если /bin/sh можно не bash.


          1. uhf
            23.11.2022 08:44

            и ничего более
            и 70 мегабайт места, не говоря уже об оперативке


        1. IAmGeorgee
          23.11.2022 09:14
          +1

          Попробуйте curlie. Тот же httpie, но на go написан


          1. Stanislavvv
            23.11.2022 09:49
            +2

            https://github.com/rs/curlie/blob/master/main.go#L141
            Если мне всё равно придётся собирать curl - накой мне обёртка?


  1. sshemol
    22.11.2022 13:51
    +1

    Сейчас бы написали на питоне, и сказали бы - купите больше памяти и ядер процессора.



  1. firehacker
    22.11.2022 17:42
    +17

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

    Между тем, есть и обратные примеры: в какой-то момент мне стало интересно, почему, начиная с определённой версии, Process Explorer Руссиновича перестал адекватно работать на Windows XP. Это была именно та версия, в которой пофиксили баг с заморозкой/разморозкой потовков. Пришлось взять дизассемблер/отладчик и пореверсить программу, чтобы выявить, какие же такие новые функции новых ОС ей теперь стали нужны для правильной работы. Оказалось, что — никакие. Ограничение было чисто искусственным и нелепым. Я написал Руссиновичу свои соображения, как проблема несовместимости может быть исправлена одной строчкой, на что она даде ответил что-то вроде «да, может, но мы не будем это чинить просто потому, что не будем и всё».
    Возможно, об этом можно написать на Хабр небольшую статью.


  1. vkni
    23.11.2022 05:15
    +1

    C11 содержит atomic'и, поэтому переход на него довольно рационален для проектов с многопоточностью. Например, OCaml 5.х работает только на C11, отбрасывая всякие legacy unix платформы.


  1. odobryabov
    23.11.2022 08:50
    +1

    Коллеги, раз такая тема, подскажите. Пишу на С уже несколько лет. Но хочется знать язык прям от и до, наизнанку. Про ABI, про память, как работают функции, ассемблер. Что почитать?


    1. sshemol
      23.11.2022 10:03
      -2

      Джеффри Рихтер "Windows для профессионалов"

      М. Руссинович, Д. Соломон - Внутреннее устройство Microsoft Windows.


      1. sshemol
        23.11.2022 18:39

        Человек спросил литературу по системным механизмам (память, конвенции вызова, процессы, потоки).

        Это лучшие книги в данной теме.


  1. win0err
    24.11.2022 15:52

    Зачем тут писать про httpie, когда curl — это не только консольная утилитка curl, но ещё и libcurl — библиотека, которую под капотом использует огромное количество проектов?

    Зачем нужно сравнивать тёплое с мягким?