Blame programming-guidelines/pt_BR/c-coding-style.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="c-coding-style" xml:lang="pt-BR">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="index#general-guidelines"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Federico Mena-Quintero</name>
Packit 1470ea
      <email its:translate="no">federico@gnome.org</email>
Packit 1470ea
      <years>2013</years>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>A equipe do GTK+</name>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>
Packit 1470ea
Packit 1470ea
    <desc>Nossas diretrizes para código C no GNOME</desc>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Rafael Fontenelle</mal:name>
Packit 1470ea
      <mal:email>rafaelff@gnome.org</mal:email>
Packit 1470ea
      <mal:years>2017</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Estilo de codificação C</title>
Packit 1470ea
Packit 1470ea
  

Esse documento apresenta o estilo de codificação preferido para programas C no GNOME. Enquanto o estilo de codificação é muito uma questão de gosto, no GNOME somos a favor de um estilo de codificação que promove consistência, legibilidade e manutenção.

Packit 1470ea
Packit 1470ea
  

Nós apresentamos exemplos de bom estilo de codificação, bem como exemplos de estilo ruim que não é aceitável no GNOME. Por favor, tente enviar patches que estejam em conformidade com o estilo de codificação do GNOME; isso indica que você fez seu dever de casa para respeitar o objetivo do projeto de manutenção a longo prazo. Patches com o estilo de codificação do GNOME também serão mais fáceis de revisar!

Packit 1470ea
Packit 1470ea
  <note>
Packit 1470ea
    

Esse documento é para código C. Para outras linguagens, veja a <link xref="index">página principal</link> das Diretrizes de programação do GNOME.

Packit 1470ea
  </note>
Packit 1470ea
Packit 1470ea
  

Essas diretrizes são fortemente inspiradas no documento “CODING-STYLE” do GTK, no “CodingStyle” do Kernel Linux e no “GNU Coding Standards”. Essas são pequenas variações entre si, com modificações particulares para cada culturas e necessidades em particular do projeto, e a versão do GNOME não é diferente.

Packit 1470ea
Packit 1470ea
  <section id="most-important-rule">
Packit 1470ea
    <title>A regra mais importante</title>
Packit 1470ea
Packit 1470ea
    

A regra mais importante quando se está escrevendo código é essa: veja o código ao redor e tente imitá-lo.

Packit 1470ea
Packit 1470ea
    

Como um mantenedor, é assustador receber um patch que obviamente está em um estilo de codificação diferente do código ao redor. Isso é desrespeitoso, como alguém pisando em uma casa impecavelmente limpa com sapatos cheios de lama.

Packit 1470ea
Packit 1470ea
    

Então, independente do que este documenta recomenda, se há código escrito e você está fazendo um patch para ele, mantenha a consistência do seu estilo atual ainda que não seja seu estilo favorito.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="line-width">
Packit 1470ea
    <title>Largura da linha</title>
Packit 1470ea
Packit 1470ea
    

Tente usar linhas de códigos entre 80 e 120 caracteres. Essa quantidade de texto é fácil de ajustar na maioria dos monitores com um tamanho de fonte decente. Linhas maiores que isso se tornam difíceis de ler, e isso pode significar que você provavelmente deveria restruturar seu código. Se você tiver um número grande de níveis de recuo, isso significa que você provavelmente deveria corrigir seu código de qualquer maneira.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="indentation">
Packit 1470ea
    <title>Recuo</title>
Packit 1470ea
Packit 1470ea
    

Em geral, há dois estilos de recuo preferidos para código no GNOME.

Packit 1470ea
Packit 1470ea
    <list type="ordered">
Packit 1470ea
      <item>
Packit 1470ea
	

Estilo do Kernel Linux. Tabulações com um comprimento de 8 caracteres são usados para recuo, com colocação de chaves de K&R:

Packit 1470ea
Packit 1470ea
	
Packit 1470ea
for (i = 0; i < num_elements; i++) {
Packit 1470ea
	foo[i] = foo[i] + 42;
Packit 1470ea
Packit 1470ea
	if (foo[i] < 35) {
Packit 1470ea
		printf ("Foo!");
Packit 1470ea
		foo[i]--;
Packit 1470ea
	} else {
Packit 1470ea
		printf ("Bar!");
Packit 1470ea
		foo[i]++;
Packit 1470ea
	}
Packit 1470ea
}
Packit 1470ea
      </item>
Packit 1470ea
Packit 1470ea
      <item>
Packit 1470ea
	

Estilo GNU. Cada novo nível possui recuo de 2 espaços, aspas vai em uma linha própria e elas também possuem recuo.

Packit 1470ea
Packit 1470ea
	
Packit 1470ea
for (i = 0; i < num_elements; i++)
Packit 1470ea
  {
Packit 1470ea
    foo[i] = foo[i] + 42;
Packit 1470ea
Packit 1470ea
    if (foo[i] < 35)
Packit 1470ea
      {
Packit 1470ea
        printf ("Foo!");
Packit 1470ea
        foo[i]--;
Packit 1470ea
      }
Packit 1470ea
    else
Packit 1470ea
      {
Packit 1470ea
        printf ("Bar!");
Packit 1470ea
        foo[i]++;
Packit 1470ea
      }
Packit 1470ea
  }
Packit 1470ea
      </item>
Packit 1470ea
    </list>
Packit 1470ea
Packit 1470ea
Packit 1470ea
    

Ambos estilos têm suas vantagens e desvantagens. O mais importante é ser consistente com o código ao redor. Por exemplo, a biblioteca GTK+, que é uma caixa de ferramentas de widgets do GNOME, é escrito com o estilo GNU. Nautilus, o gerenciador de arquivos do GNOME, é escrito no estilo Kernel Linux. Ambos estilos são perfeitamente legíveis e consistentes quando você se acostuma com eles.

Packit 1470ea
Packit 1470ea
    

Seu primeiro sentimento ao ter que estudar ou trabalhar em um pedaço de código que não seja seu preferido em estilo de recuo pode ser, como vamos colocá-lo, desconfortável. Você deve resistir sua inclinação em ajustar o recuo de tudo, ou usar um estilo inconsistente para seu patch. Lembre-se da primeira regra: ser consistente e respeitoso com os costumes do código, e seus patches terão uma chance muito mais alta de serem aceitos sem muita argumentação sobre o estilo de recuo correto.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="tab-characters">
Packit 1470ea
    <title>Caracteres de tabulações</title>
Packit 1470ea
Packit 1470ea
    

Não altere o tamanho dos tabs em seu editor; deixe-os como 8 espaços. Alterar o tamanho dos tabs naquele código que você não escreveu estará perpetuamente desalinhada.

Packit 1470ea
Packit 1470ea
    

Em vez disso, defina o tamanho do recuo conforme apropriado para o código que você está editando. Quando se está escrevendo em algo diferente do estilo Kernel Linux, você pode está querer dizer ao seu editor para converter todas os tabs para 8 espaços, de forma que não haja ambiguidade sobre a quantidade de espaços.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="braces">
Packit 1470ea
    <title>Chaves</title>
Packit 1470ea
Packit 1470ea
    

Chaves não devem ser usadas para blocos de instrução singular:

Packit 1470ea
Packit 1470ea
Packit 1470ea
/* válido */
Packit 1470ea
if (condição)
Packit 1470ea
	single_statement ();
Packit 1470ea
else
Packit 1470ea
	another_single_statement (arg1);
Packit 1470ea
Packit 1470ea
	

A regra de “nenhum bloco para instruções singulares” possui apenas quatro exceções:

Packit 1470ea
Packit 1470ea
	<list type="ordered">
Packit 1470ea
          <item>
Packit 1470ea
            

No estilo GNU, se qualquer um dos lados de uma instrução if-else possui chaves, ambos lados deveriam ter, para corresponder o recuo:

Packit 1470ea
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
if (condição)
Packit 1470ea
  {
Packit 1470ea
    foo ();
Packit 1470ea
    bar ();
Packit 1470ea
  }
Packit 1470ea
else
Packit 1470ea
  {
Packit 1470ea
    baz ();
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if (condição)
Packit 1470ea
  {
Packit 1470ea
    foo ();
Packit 1470ea
    bar ();
Packit 1470ea
  }
Packit 1470ea
else
Packit 1470ea
  baz ();
Packit 1470ea
          </item>
Packit 1470ea
Packit 1470ea
	  <item>
Packit 1470ea
	    

Se a instrução singular cobre múltiplas linhas (ex.: para funções com muitos argumentos) e é seguido por else ou eles if:

Packit 1470ea
Packit 1470ea
Packit 1470ea
/* estilo Kernel Linux válido */
Packit 1470ea
if (condição) {
Packit 1470ea
	uma_instrução_singular_com_muitos_args (algum_argumento_comprido,
Packit 1470ea
						outro_argumento_comprido,
Packit 1470ea
						e_mais_um_outro,
Packit 1470ea
						mais_um);
Packit 1470ea
} else
Packit 1470ea
	outro_arg_singular (arg1, arg2);
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
if (condição)
Packit 1470ea
  {
Packit 1470ea
    uma_instrução_singular_com_muitos_args (algum_argumento_comprido,
Packit 1470ea
                                            outro_argumento_comprido,
Packit 1470ea
                                            e_mais_um_outro,
Packit 1470ea
                                            mais_um);
Packit 1470ea
  }
Packit 1470ea
else
Packit 1470ea
  {
Packit 1470ea
    outro_arg_singular (arg1, arg2);
Packit 1470ea
  }
Packit 1470ea
          </item>
Packit 1470ea
Packit 1470ea
          <item>
Packit 1470ea
            

Se a condição for composta de muitas linhas:

Packit 1470ea
Packit 1470ea
Packit 1470ea
/* estilo Kernel Linux válido */
Packit 1470ea
if (condição1 ||
Packit 1470ea
    (condição2 && condição3) ||
Packit 1470ea
    condição4 ||
Packit 1470ea
    (condição5 && (condição6 || condição7))) {
Packit 1470ea
	uma_instrução_singular ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
if (condição1 ||
Packit 1470ea
    (condição2 && condição3) ||
Packit 1470ea
    condição4 ||
Packit 1470ea
    (condição5 && (condição6 || condição7)))
Packit 1470ea
  {
Packit 1470ea
    uma_instrução_singular ();
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
            

Note que tais condições longas são geralmente difíceis de entender. Uma boa prática é definir essa condição para uma variável booleana, com um bom nome para aquela variável. Uma outra forma é mover a condição longa para uma função.

Packit 1470ea
          </item>
Packit 1470ea
Packit 1470ea
          <item>
Packit 1470ea
            

ifs aninhados, caso em que o bloco deve ser colocado if mais extremo:

Packit 1470ea
Packit 1470ea
Packit 1470ea
/* estilo Kernel Linux válido */
Packit 1470ea
if (condição) {
Packit 1470ea
	if (outra_condição)
Packit 1470ea
		instrução_singular ();
Packit 1470ea
	else
Packit 1470ea
		outra_instrução_singular ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
if (condição)
Packit 1470ea
  {
Packit 1470ea
    if (outra_condição)
Packit 1470ea
      instrução_singular ();
Packit 1470ea
    else
Packit 1470ea
      outra_instrução_singular ();
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if (condição)
Packit 1470ea
	if (outra_condição)
Packit 1470ea
		instrução_singular ();
Packit 1470ea
	else if (mais_uma_condição)
Packit 1470ea
		outra_instrução_singular ();
Packit 1470ea
          </item>
Packit 1470ea
        </list>
Packit 1470ea
Packit 1470ea
        

Em geral, novos blocos devem ser colocados em um novo nível de recuo, como este:

Packit 1470ea
Packit 1470ea
        
Packit 1470ea
int retval = 0;
Packit 1470ea
Packit 1470ea
instrucao_1 ();
Packit 1470ea
instrucao_2 ();
Packit 1470ea
Packit 1470ea
{
Packit 1470ea
	int var1 = 42;
Packit 1470ea
	gboolean res = FALSE;
Packit 1470ea
Packit 1470ea
	res = instrucao_3 (var1);
Packit 1470ea
Packit 1470ea
	retval = res ? -1 : 1;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
        

Enquanto chaves para definições de função devem ficar em uma nova linha, elas não devem adicionar um novo nível de recuo:

Packit 1470ea
Packit 1470ea
        
Packit 1470ea
/* estilo Kernel Linux válido */
Packit 1470ea
static void
Packit 1470ea
minha_funcao (int argumento)
Packit 1470ea
{
Packit 1470ea
	faz_minhas_coisas ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
static void
Packit 1470ea
minha_funcao (int argumento)
Packit 1470ea
{
Packit 1470ea
  faz_minhas_coisas ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
static void
Packit 1470ea
minha_funcao (int argumento) {
Packit 1470ea
	faz_minhas_coisas ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
static void
Packit 1470ea
minha_funcao (int argumento)
Packit 1470ea
  {
Packit 1470ea
    faz_minhas_coisas ();
Packit 1470ea
  }
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="conditions">
Packit 1470ea
    <title>Condições</title>
Packit 1470ea
Packit 1470ea
    

Não verifique valores booleanos por igualdade. Ao usar comparações implícitas, o código resultante pode ser mais parecido com o inglês conversacional. Um outro fundamento é que um valor ‘verdadeiro’ não necessariamente será igual a macro TRUE usada. Por exemplo:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* inválido */
Packit 1470ea
if (localizado == TRUE)
Packit 1470ea
	fazer_foo ();
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if (localizado == FALSE)
Packit 1470ea
	fazer_bar ();
Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* válido */
Packit 1470ea
if (localizado)
Packit 1470ea
	fazer_foo ();
Packit 1470ea
Packit 1470ea
/* válido */
Packit 1470ea
if (!localizado)
Packit 1470ea
	fazer_bar ();
Packit 1470ea
Packit 1470ea
    

A linguagem C usa o valor 0 para muitos propósitos. Como um valor numérico, o fim de uma string, um ponteiro nulo e o booleano FALSE. Para tornar o código mais limpo, você deveria escrever código que realça a forma específica que 0 é usado. Então, ao ler uma comparação, é possível saber o tipo de variável. Para variáveis booleanas, uma comparação implícita é apropriado porque já é uma expressão lógica. Outros tipos de variáveis que não são expressões lógicas por si só, então uma comparação explícita é melhor:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* válido */
Packit 1470ea
if (algum_ponteiro == NULL)
Packit 1470ea
	fazer_blá ();
Packit 1470ea
Packit 1470ea
/* válido */
Packit 1470ea
if (número == 0)
Packit 1470ea
	fazer_foo ();
Packit 1470ea
Packit 1470ea
/* válido */
Packit 1470ea
if (str != NULL && *str != '\0')
Packit 1470ea
	fazer_bar ();
Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* inválido */
Packit 1470ea
if (!algum_ponteiro)
Packit 1470ea
	fazer_blá ();
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if (!número)
Packit 1470ea
	fazer_foo ();
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if (str && *str)
Packit 1470ea
	fazer_bar ();
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="functions">
Packit 1470ea
    <title>Funções</title>
Packit 1470ea
Packit 1470ea
    

Funções devem ser declaradas colocando o valor de retorno em uma linha separada do nome da função:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
void
Packit 1470ea
minha_funcao (void)
Packit 1470ea
{
Packit 1470ea
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
    

A lista de argumentos deve estar quebrada em nova linha para cada argumento, com os nomes dos argumentos alinhados à direita, levando em consideração os ponteiros:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
void
Packit 1470ea
minha_funcao (algum_tipo_t    tipo,
Packit 1470ea
              outro_tipo_t   *um_ponteiro,
Packit 1470ea
              double_ptr_t  **ponteiro_duplo,
Packit 1470ea
              tipo_final_t    outro_tipo)
Packit 1470ea
{
Packit 1470ea
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
    

Se você usa Emacs, você pode usar M-x align para fazer esse tipo de alinhamento automaticamente. Basca colocar o ponteiro e marcar em volta do protótipo da função e invocar aquele comando.

Packit 1470ea
Packit 1470ea
    

O alinhamento também se mantém ao invocar uma função sem quebrar o limite de comprimento da linha:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
alinha_args_de_funcoes (primeiro_argumento,
Packit 1470ea
                        segundo_argumento,
Packit 1470ea
                        terceiro_argumento);
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="whitespace">
Packit 1470ea
    <title>Espaço em branco</title>
Packit 1470ea
Packit 1470ea
    

Sempre coloque espaço antes de abrir parênteses, mas nunca após:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* válido */
Packit 1470ea
if (condição)
Packit 1470ea
	faz_minhas_coisas ();
Packit 1470ea
Packit 1470ea
/* válido */
Packit 1470ea
switch (condição) {
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if(condição)
Packit 1470ea
	faz_minhas_coisas();
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
if ( condição )
Packit 1470ea
	faz_minhas_coisas ( );
Packit 1470ea
Packit 1470ea
    

Ao declarar um tipo de estrutura, use novas linhas para separar seções lógicas da estrutura:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
struct _GtkWrapBoxPrivate
Packit 1470ea
{
Packit 1470ea
	GtkOrientation        orientation;
Packit 1470ea
	GtkWrapAllocationMode mode;
Packit 1470ea
Packit 1470ea
	GtkWrapBoxSpreading   horizontal_spreading;
Packit 1470ea
	GtkWrapBoxSpreading   vertical_spreading;
Packit 1470ea
Packit 1470ea
	guint16               vertical_spacing;
Packit 1470ea
	guint16               horizontal_spacing;
Packit 1470ea
Packit 1470ea
	guint16               minimum_line_children;
Packit 1470ea
	guint16               natural_line_children;
Packit 1470ea
Packit 1470ea
	GList                *children;
Packit 1470ea
};
Packit 1470ea
Packit 1470ea
    

Não elimine espaços em branco e novas linhas apenas por que alguma coisa caberia em uma única linha:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* inválido */
Packit 1470ea
if (condição) foo (); else bar ();
Packit 1470ea
Packit 1470ea
    

Elimine espaços em branco de qualquer linha, preferivelmente como um patch ou commit separado. Nunca use linhas vazias no começo ou no fim de um arquivo.

Packit 1470ea
Packit 1470ea
    

Essa é uma pequena função de Emacs que você pode usar para limpar linhas terminando com espaço em branco:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
(defun clean-line-ends ()
Packit 1470ea
  (interactive)
Packit 1470ea
  (if (not buffer-read-only)
Packit 1470ea
      (save-excursion
Packit 1470ea
	(goto-char (point-min))
Packit 1470ea
	(let ((count 0))
Packit 1470ea
	  (while (re-search-forward "[ 	]+$" nil t)
Packit 1470ea
	    (setq count (+ count 1))
Packit 1470ea
	    (replace-match "" t t))
Packit 1470ea
	  (message "Limpadas %d linhas" count)))))
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="switch">
Packit 1470ea
    <title>A instrução switch</title>
Packit 1470ea
Packit 1470ea
    

Um switch deve abrir um bloco em um novo nível de recuo, e cada case deve iniciar no mesmo nível de recuo que as chaves, com o bloco de case em um novo nível de recuo:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* estilo Kernel Linux válido */
Packit 1470ea
switch (condição) {
Packit 1470ea
case FOO:
Packit 1470ea
	fazer_foo ();
Packit 1470ea
	break;
Packit 1470ea
Packit 1470ea
case BAR:
Packit 1470ea
	fazer_bar ();
Packit 1470ea
	break;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
switch (condição)
Packit 1470ea
  {
Packit 1470ea
  case FOO:
Packit 1470ea
    fazer_foo ();
Packit 1470ea
    break;
Packit 1470ea
Packit 1470ea
  case BAR:
Packit 1470ea
    fazer_bar ();
Packit 1470ea
    break;
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
switch (condição) {
Packit 1470ea
  case FOO: fazer_foo (); break;
Packit 1470ea
  case BAR: fazer_bar (); break;
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
switch (condição)
Packit 1470ea
  {
Packit 1470ea
  case FOO: fazer_foo ();
Packit 1470ea
    break;
Packit 1470ea
  case BAR: fazer_bar ();
Packit 1470ea
    break;
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
/* inválido */
Packit 1470ea
switch (condição)
Packit 1470ea
  {
Packit 1470ea
    case FOO:
Packit 1470ea
    fazer_foo ();
Packit 1470ea
    break;
Packit 1470ea
    case BAR:
Packit 1470ea
    fazer_bar ();
Packit 1470ea
    break;
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
    

É preferível, apesar de não ser obrigatório, separar os vários cases com uma nova linha:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
switch (condição) {
Packit 1470ea
case FOO:
Packit 1470ea
	fazer_foo ();
Packit 1470ea
	break;
Packit 1470ea
Packit 1470ea
case BAR:
Packit 1470ea
	fazer_foo ();
Packit 1470ea
	break;
Packit 1470ea
Packit 1470ea
default:
Packit 1470ea
	fazer_padrão ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
    

A instrução break para o caso default não é obrigatório.

Packit 1470ea
Packit 1470ea
    

Se alternando sobre um tipo enumerado, uma instrução case deve existir para cada novo membro do tipo enumerado. Para membros que você não deseja tratar, apelide suas instruções case para default:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
switch (condição_enumerada) {
Packit 1470ea
case TRATADA_1:
Packit 1470ea
	fazer_foo ();
Packit 1470ea
	break;
Packit 1470ea
Packit 1470ea
case TRATADA_2:
Packit 1470ea
	fazer_bar ();
Packit 1470ea
	break;
Packit 1470ea
Packit 1470ea
case IGNORADA_1:
Packit 1470ea
case IGNORADA_2:
Packit 1470ea
default:
Packit 1470ea
	fazer_padrão ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
    

Se a maioria dos membros do tipo enumerado não deve ser tratada, considere usar uma instrução if em vez de um switch.

Packit 1470ea
Packit 1470ea
    

Se um bloco case precisa declarar novas variáveis, as mesmas regras que os blocos internos se aplicam (veja acima); a instrução break deve ser colocada fora do bloco interno:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
/* estilo GNU válido */
Packit 1470ea
switch (condição)
Packit 1470ea
  {
Packit 1470ea
  case FOO:
Packit 1470ea
    {
Packit 1470ea
      int foo;
Packit 1470ea
Packit 1470ea
      foo = fazer_foo ();
Packit 1470ea
    }
Packit 1470ea
    break;
Packit 1470ea
Packit 1470ea
Packit 1470ea
  }
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="header-files">
Packit 1470ea
    <title>Arquivos de cabeçalho</title>
Packit 1470ea
Packit 1470ea
    

A única regra importante para cabeçalhos é que as definições de funções devem estar alinhados verticalmente em três colunas:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
tipo_retorno          nome_funcao            (tipo   argumento,
Packit 1470ea
                                              tipo   argumento,
Packit 1470ea
                                              tipo   argumento);
Packit 1470ea
Packit 1470ea
    

A largura máxima de cada coluna é dada pelo elemento mais longo na coluna:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
void         gtk_type_set_property (GtkType      *type,
Packit 1470ea
                                    const gchar  *value,
Packit 1470ea
                                    GError      **error);
Packit 1470ea
const gchar *gtk_type_get_property (GtkType      *type);
Packit 1470ea
Packit 1470ea
    

Também é possível alinhar as colunas à próxima tabulação:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
void          gtk_type_set_prop           (GtkType *type,
Packit 1470ea
                                           gfloat   value);
Packit 1470ea
gfloat        gtk_type_get_prop           (GtkType *type);
Packit 1470ea
gint          gtk_type_update_foobar      (GtkType *type);
Packit 1470ea
Packit 1470ea
    

Como anteriormente, você pode usar M-x align no Emacs para fazer isso automaticamente.

Packit 1470ea
Packit 1470ea
    

Se você está criando uma biblioteca pública, tente exportar um único arquivo de cabeçalho público que, por sua vez, inclua todos os arquivos de cabeçalhos menores nele. Isto é para que cabeçalhos públicos nunca seja incluídos diretamente; em vez disso, uma única inclusão é usada nos aplicativos. Por exemplo, GTK+ usa o seguinte em seus arquivos de cabeçalhos que não devem ser incluídos diretamente por aplicativos:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
Packit 1470ea
#error "Only <gtk/gtk.h> can be included directly."
Packit 1470ea
#endif
Packit 1470ea
Packit 1470ea
    

Para bibliotecas, todos cabeçalhos devem ter proteções de inclusão (para uso interno) e proteções de C++ ou, em inglês, #include guards e C++ guards. Estas fornece a mágica extern "C" que C++ requer para incluir cabeçalhos de C simples:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
#ifndef MYLIB_FOO_H_
Packit 1470ea
#define MYLIB_FOO_H_
Packit 1470ea
Packit 1470ea
#include <gtk/gtk.h>
Packit 1470ea
Packit 1470ea
G_BEGIN_DECLS
Packit 1470ea
Packit 1470ea
Packit 1470ea
Packit 1470ea
G_END_DECLS
Packit 1470ea
Packit 1470ea
#endif /* MYLIB_FOO_H_ */
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="gobject">
Packit 1470ea
    <title>Classes de GObject</title>
Packit 1470ea
Packit 1470ea
    

Definições e implementações de classe GObject exigem algumas notas adicionais de estilo de codificação, e devem sempre estar sob <link xref="namespacing#gobject">espaço de nome correto</link>.

Packit 1470ea
Packit 1470ea
    

Declarações Typedef devem ser colocadas no começo do arquivo:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
typedef struct _GtkBoxedStruct       GtkBoxedStruct;
Packit 1470ea
typedef struct _GtkMoreBoxedStruct   GtkMoreBoxedStruct;
Packit 1470ea
Packit 1470ea
    

Isso inclui tipos de enumeração:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
typedef enum
Packit 1470ea
{
Packit 1470ea
  GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT,
Packit 1470ea
  GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH
Packit 1470ea
} GtkSizeRequestMode;
Packit 1470ea
Packit 1470ea
    

A tipos de retorno de chamada (callback):

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
typedef void (* GtkCallback) (GtkWidget *widget,
Packit 1470ea
                              gpointer   user_data);
Packit 1470ea
Packit 1470ea
    

Estruturas de instâncias devem ser declaradas usando G_DECLARE_FINAL_TYPE ou G_DECLARE_DERIVABLE_TYPE:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
#define GTK_TYPE_FOO (gtk_foo_get_type ())
Packit 1470ea
G_DECLARE_FINAL_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)
Packit 1470ea
Packit 1470ea
    

Para tipos finais, dados privados podem ser armazenados em um objeto struct, o qual deve ser definido no arquivo C:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
struct _GtkFoo
Packit 1470ea
{
Packit 1470ea
  GObject   instancia_pai;
Packit 1470ea
Packit 1470ea
  guint     dados_privados;
Packit 1470ea
  gpointer  mais_dados_privados;
Packit 1470ea
};
Packit 1470ea
Packit 1470ea
    

Para tipos deriváveis, dados privados devem estar armazenados em um struct privado no arquivo C, configurado usando G_DEFINE_TYPE_WITH_PRIVATE() e acessado usando uma função _get_instance_private():

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
#define GTK_TYPE_FOO gtk_foo_get_type ()
Packit 1470ea
G_DECLARE_DERIVABLE_TYPE (GtkFoo, gtk_foo, GTK, FOO, GtkWidget)
Packit 1470ea
Packit 1470ea
struct _GtkFooClass
Packit 1470ea
{
Packit 1470ea
  GtkWidgetClass parent_class;
Packit 1470ea
Packit 1470ea
  void (* handle_frob)  (GtkFrobber *frobber,
Packit 1470ea
                         guint       n_frobs);
Packit 1470ea
Packit 1470ea
  gpointer padding[12];
Packit 1470ea
};
Packit 1470ea
Packit 1470ea
    

Sempre use as macros G_DEFINE_TYPE(), G_DEFINE_TYPE_WITH_PRIVATE() e G_DEFINE_TYPE_WITH_CODE() ou suas variantes abstratas G_DEFINE_ABSTRACT_TYPE(), G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE() e G_DEFINE_ABSTRACT_TYPE_WITH_CODE(); também, use as macros similares para definir interfaces e tipos “boxed”.

Packit 1470ea
Packit 1470ea
    

Tipos de interfaces devem sempre ter um typedef dummy visando as chamadas:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
typedef struct _GtkFooable          GtkFooable;
Packit 1470ea
Packit 1470ea
    

A estrutura da interface deve ter ‘Interface’ pós-fixado ao typedef dummy:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
typedef struct _GtkFooableInterface     GtkFooableInterface;
Packit 1470ea
Packit 1470ea
    

Interfaces devem ter as seguintes macros:

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
      
Packit 1470ea
	
Packit 1470ea
	  

Macro

Packit 1470ea
	  

Expande para

Packit 1470ea
	
Packit 1470ea
      
Packit 1470ea
      
Packit 1470ea
	
Packit 1470ea
	  

GTK_TYPE_iface_name

Packit 1470ea
	  

iface_name_get_type

Packit 1470ea
	
Packit 1470ea
	
Packit 1470ea
	  

GTK_iface_name

Packit 1470ea
	  

G_TYPE_CHECK_INSTANCE_CAST

Packit 1470ea
	
Packit 1470ea
	
Packit 1470ea
	  

GTK_IS_iface_name

Packit 1470ea
          

G_TYPE_CHECK_INSTANCE_TYPE

Packit 1470ea
	
Packit 1470ea
	
Packit 1470ea
	  

GTK_iface_name_GET_IFACE

Packit 1470ea
          

G_TYPE_INSTANCE_GET_INTERFACE

Packit 1470ea
	
Packit 1470ea
      
Packit 1470ea
    
Packit 1470ea
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="memory-allocation">
Packit 1470ea
    <title>Alocação de memória</title>
Packit 1470ea
Packit 1470ea
    

Quando se estiver alocando dados em uma pilha, use g_new().

Packit 1470ea
Packit 1470ea
    

Tipos de estrutura pública devem sempre ser retornados após serem zerados, seja explicitamente para cada membro, seja usando g_new0().

Packit 1470ea
Packit 1470ea
    

Veja <link xref="memory-management"/> para mais detalhes.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="macros">
Packit 1470ea
    <title>Macros</title>
Packit 1470ea
Packit 1470ea
    

Tente evitar macros privadas, a menos que seja estritamente necessário. Lembre-se de usar #undef nelas no final de um bloco ou uma série de funções que precisem delas.

Packit 1470ea
Packit 1470ea
    

Funções em linha são geralmente preferíveis a macros privadas.

Packit 1470ea
Packit 1470ea
    

Macros públicas não devem ser usadas a menos que elas sejam avaliadas para uma constante.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="public-api">
Packit 1470ea
    <title>API pública</title>
Packit 1470ea
Packit 1470ea
    

Evite exportar variáveis como API pública, já que isso pode ser pesado demais para algumas plataformas. Em vez disso, é sempre preferível adicionar “gets” e “sets”. Também, cuidado com variáveis globais em geral.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="private-api">
Packit 1470ea
    <title>API privada</title>
Packit 1470ea
Packit 1470ea
    

Funções não exportadas que são necessárias em mais de um arquivo fonte devem ser prefixadas com um sublinhado (‘_’) e declarados em um arquivo de cabeçalho privado. Por exemplo, _minhalib_foo_interno().

Packit 1470ea
Packit 1470ea
    

Funções prefixadas com sublinhado nunca são exportadas.

Packit 1470ea
Packit 1470ea
    

Funções não exportadas que são necessárias apenas em um arquivo fonte devem ser declaradas com estáticas.

Packit 1470ea
  </section>
Packit 1470ea
</page>