Последнее обновление:2026-10-12
Памятка по разработке на C++ с libcurl¶
Единый стиль кода помогает командной работе и ревью кода; в индустрии чаще всего используется стиль google, а в этом разделе рассмотрим кое-что другое — посмотрим, каковы стандарты кода команды curl, инструмента, которым мы пользуемся довольно часто.
Пару слов о curl: он очень удобен для передачи данных в командной строке или скриптах, вы наверняка им пользовались; исходный код можно посмотреть на github
Теперь рассмотрим стандарты разработки на C команды curl по нескольким аспектам.
Именование¶
Названия новых функций и переменных должны быть логичными, понятными и отражать их назначение.
Функции, локальные для файла, следует объявлять статическими; рекомендуется использовать строчные буквы в названиях.
Отступы¶
Используйте для отступов только пробелы, без табуляции. На каждую новую открывающую фигурную скобку — два пробела.
Комментарии¶
Поскольку пишется код C89, комментарии // не разрешены — они появились только в стандарте C99. Используйте только /* комментарии */.
Длина строк¶
Исходный код в curl никогда не должен превышать 79 колонок, и даже в эпоху современных больших экранов и высокого разрешения есть две причины это соблюдать:
- Более узкие колонки читать легче, чем широкие. Не случайно газеты десятилетиями и даже веками используют колонки.
- Более узкие колонки позволяют разработчикам легче размещать несколько фрагментов кода рядом в разных окнах. Это даёт возможность показать на одном экране два-три окна с исходным кодом, а также несколько терминалов и окон отладки.
Фигурные скобки¶
В выражениях if/while/do/for открывающую фигурную скобку мы пишем на той же строке, что и ключевое слово, а закрывающую — на отдельной строке с тем же уровнем отступа, что и начальное ключевое слово. Вот так:
Если внутри только один однострочный оператор, скобки можно опустить: Для функций открывающая скобка должна быть на отдельной строке:'else' на следующей строке¶
При добавлении clauses else к условному выражению с фигурными скобками мы помещаем его на новой строке после закрывающей скобки. Вот так:
Без пробела перед скобкой¶
В выражениях if/while/do/for между ключевым словом и открывающей скобкой не должно быть пробела. Вот так:
Используйте булевы условия¶
В условиях if/while мы предпочитаем проверять значение условия как булево с TRUE или FALSE, указатель с NULL или != NULL, а целое — с нулём или ненулевым значением, а не так:
Не присваивайте в условиях¶
Для улучшения читаемости и снижения сложности условий избегайте присваивания переменных в условиях if/while. Такой стиль не одобряется:
Вместо этого поощряется более ясное выражение:Новый блок на новой строке¶
Никогда не пишите несколько операторов в одной строке — даже короткие условия if() не исключение.
И никогда так:Пробелы вокруг операторов¶
Используйте пробелы с обеих сторон операторов в C-выражениях. Исключение — постфиксные (), [], ->, ., ++, -- и унарные +, -, !, ~, & операторы: перед ними пробелов быть не должно.
Примеры:
bla = func();
who = name[0];
age += 1;
true = !false;
size += -2 + 3 *
(a + b);
ptr->member = a++;
struct.field = b--;
ptr = &address;
contents = *pointer;
complement = ~bits;
empty = (!*string) ? TRUE : FALSE;
Возвращаемое значение без скобок¶
Не ставьте лишних скобок в операторе 'return':
Аргумент sizeof в скобках¶
Используя в коде оператор sizeof, мы предпочитаем заключать его аргумент в скобки:
Выравнивание по колонкам¶
Некоторые операторы невозможно уместить в одной строке: строка слишком длинна, оператор трудночитаем или действуют другие описанные выше правила стиля. В таких случаях оператор разбивается на несколько строк.
Если продолжающая строка является частью выражения или подвыражения, следует выравнивать её по подходящей колонке, чтобы было ясно, частью какого оператора она является. Оператор не должен начинаться с продолжающей строки. В остальных случаях придерживайтесь правила отступа в 2 пробела. Вот несколько примеров из libcurl:
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
(handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
(handle->set.httpreq == HTTPREQ_GET ||
handle->set.httpreq == HTTPREQ_HEAD))
/* 没有要求 HTTP/1.0 并且是 GET 或 HEAD 请求 */
return TRUE;
data->set.http_disable_hostname_check_before_authentication =
(0 != va_arg(param, long)) ? TRUE : FALSE;
if(option) {
result = parse_login_details(option, strlen(option),
(userp ? &user : NULL),
(passwdp ? &passwd : NULL),
NULL);
}
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
"server response left\n",
(int)clipamount));
Платформозависимый код¶
Используйте #ifdef HAVE_FEATURE для условного кода. Мы избегаем проверки конкретной операционной системы или оборудования в строках #ifdef. HAVE_FEATURE должен генерироваться скриптом configure для Unix-подобных систем, а для остальных систем жёстко задаваться в файлах config-[system].h.
Мы также рекомендуем при сборке libcurl использовать макросы/функции, которые могут быть пустыми или определены как константы, чтобы код был бесшовным. Как в этом примере, где функция magic() работает по-разному в зависимости от условий сборки:
#ifdef HAVE_MAGIC
void magic(int a)
{
return a + 2;
}
#else
#define magic(x) 1
#endif
int content = magic(3);
Не делайте typedef для структур¶
Хотя структуры использовать можно, делать для них typedef не следует. Обозначайте их как struct name:
Примечание
Это памятка для разработки; рекомендуется сверяться с официальной документацией libcurl и разбирать коды ошибок конкретного проекта.
Похожие темы¶
- Шесть способов разделения строк в C++ | C++那些事
- Заметки о разработке расширений CPython | C++那些事
- Как читать открытый C++-код | C++那些事
- Интересный фрагмент C++-кода | C++那些事
- Печать чисел от 1 до 100 без циклов в C++ | C++那些事