Última atualização:2026-10-12
Notas de desenvolvimento com libcurl em C++¶
Um estilo de código uniforme facilita a colaboração da equipe e a revisão de código; o mais usado na indústria é o estilo do google. Nesta seção, algo diferente: vamos ver como é o padrão de código da equipe do curl, uma ferramenta que usamos com muita frequência.
Sobre o curl, em resumo: ele é muito útil para transferir dados em linha de comando ou em scripts, e você certamente já o usou; sua implementação pode ser consultada no github
A seguir, vamos olhar as normas de desenvolvimento em C do curl por vários ângulos.
Nomenclatura¶
Nomes novos de funções e variáveis devem ser lógicos, compreensíveis e nomeados de acordo com sua finalidade.
Funções locais de arquivo devem ser declaradas como estáticas, e recomenda-se usar nomes em letras minúsculas.
Indentação¶
Use apenas espaços para indentar, nunca tabulações. Cada nova chave de abertura usa dois espaços.
Comentários¶
Como se escreve código C89, não são permitidos comentários //. Eles só foram introduzidos no padrão C99. Use apenas /* comentários */.
Linhas longas¶
O código-fonte do curl nunca deve ultrapassar 79 colunas; mesmo na era das telas grandes e de alta resolução, ainda há dois motivos para manter isso:
- Colunas mais estreitas são mais fáceis de ler que colunas largas. Há um motivo pelos quais os jornais usam colunas há décadas, até séculos.
- Colunas mais estreitas permitem que os desenvolvedores exibam mais facilmente vários trechos de código lado a lado em janelas diferentes. Isso permite mostrar dois ou três arquivos de código-fonte lado a lado na mesma tela — além de vários terminais e janelas de depuração.
Chaves¶
Em expressões if/while/do/for, escrevemos a chave de abertura na mesma linha da palavra-chave e colocamos a chave de fechamento em uma linha no mesmo nível de indentação da palavra-chave inicial. Assim:
Se contiverem apenas uma instrução de uma linha, as chaves podem ser omitidas: Para funções, a chave de abertura deve ficar em uma linha separada:'else' na linha seguinte¶
Ao adicionar uma cláusula else a uma expressão condicional usando chaves, adicionamo-la em uma nova linha após a chave de fechamento. Assim:
Sem espaço antes dos parênteses¶
Ao usar expressões if/while/do/for, não deve haver espaço entre a palavra-chave e o parêntese de abertura. Assim:
Usar condições booleanas¶
Em condições if/while, preferimos testar o valor da condição, como booleanos com TRUE ou FALSE, ponteiros com NULL ou != NULL, e inteiros com zero ou diferente de zero, em vez de:
Não atribuir dentro de condições¶
Para aumentar a legibilidade e reduzir a complexidade das condições, evite atribuições de variáveis em condições if/while. Este estilo é desaprovado:
Prefira expressar com mais clareza:Novo bloco em nova linha¶
Nunca se escrevem vários comandos na mesma linha, nem mesmo para condições if() curtas.
Nunca assim:Espaços ao redor dos operadores¶
Use espaços nos dois lados dos operadores em expressões C. Exceto os operadores de sufixo (), [], ->, ., ++, -- e os unários +, -, !, ~, &, que não devem ter espaços.
Exemplo:
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;
Valor de retorno sem parênteses¶
Não coloque parênteses extras no comando 'return':
Parâmetro de sizeof com parênteses¶
Ao usar o operador sizeof no código, preferimos colocar parênteses ao redor do seu argumento:
Alinhamento de colunas¶
Alguns comandos não podem ser completos em uma única linha porque a linha é longa demais, o comando é difícil de ler, ou por outras diretrizes de estilo acima. Nesses casos, o comando se estende por várias linhas.
Se uma linha contínua faz parte de uma expressão ou subexpressão, você deve alinhá-la na coluna adequada para que se perceba claramente de qual parte do comando ela faz. Os operadores não devem começar em linhas contínuas. Nos demais casos, siga a diretriz de indentação de 2 espaços. Aqui estão alguns exemplos do 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));
Código dependente de plataforma¶
Use #ifdef HAVE_FEATURE para código condicional. Evitamos verificar um sistema operacional ou hardware específico em linhas #ifdef. HAVE_FEATURE deve ser gerado pelo script configure para sistemas do tipo Unix, e eles são definidos diretamente nos arquivos config-[system].h de outros sistemas.
Também incentivamos o uso, quando o libcurl é compilado, de macros/funções que podem ser vazias ou definidas como constantes, para que o código fique sem emendas. Como neste exemplo, em que a função magic() funciona de forma diferente conforme as condições da compilação:
#ifdef HAVE_MAGIC
void magic(int a)
{
return a + 2;
}
#else
#define magic(x) 1
#endif
int content = magic(3);
Não use typedef em estruturas¶
Embora seja possível usar estruturas, não faça typedef delas. Identifique-as com a forma struct name:
Nota
Este texto serve como memorando de desenvolvimento; recomenda-se consultá-lo junto com a documentação oficial do libcurl e a análise dos códigos de erro do projeto específico.
Tópicos relacionados¶
- Seis métodos de divisão de strings em C++ | C++那些事
- Notas sobre desenvolvimento de extensões CPython | C++那些事
- Como ler código C++ open source | C++那些事
- Um trecho de código C++ interessante | C++那些事
- Imprimir de 1 a 100 em C++ sem laços | C++那些事