xref: /linux/Documentation/translations/pt_BR/process/coding-style.rst (revision 14c897740388216acd59477a382de327d5e27ba4)
1d5ac3d36SDaniel Pereira.. SPDX-License-Identifier: GPL-2.0
2d5ac3d36SDaniel Pereira
3*6d1f5609SDaniel Pereira.. _pt_BR_codingstyle:
4*6d1f5609SDaniel Pereira
5d5ac3d36SDaniel PereiraEstilo de codificação do kernel Linux
6d5ac3d36SDaniel Pereira=====================================
7d5ac3d36SDaniel Pereira
8d5ac3d36SDaniel PereiraEste é um breve documento descrevendo o estilo de codificação preferido
9d5ac3d36SDaniel Pereirapara o kernel Linux. O estilo de codificação é muito pessoal, e eu não
10d5ac3d36SDaniel Pereira**forçarei** minhas opiniões a ninguém, mas isso é o que vale para tudo
11d5ac3d36SDaniel Pereiraque eu tenha que manter, e eu preferiria isso para a maioria das outras
12d5ac3d36SDaniel Pereiracoisas também. Por favor, considere pelo menos os pontos aqui apresentados.
13d5ac3d36SDaniel Pereira
14d5ac3d36SDaniel PereiraPrimeiramente, eu sugiro imprimir uma cópia dos padrões de codificação do GNU,
15d5ac3d36SDaniel Pereirae NÃO lê-la. Queime-as, é um grande gesto simbólico.
16d5ac3d36SDaniel Pereira
17d5ac3d36SDaniel PereiraDe qualquer forma, aqui vai:
18d5ac3d36SDaniel Pereira
19d5ac3d36SDaniel Pereira
20d5ac3d36SDaniel Pereira1) Indentação
21d5ac3d36SDaniel Pereira-------------
22d5ac3d36SDaniel Pereira
23d5ac3d36SDaniel PereiraAs tabulações têm 8 caracteres, e portanto as indentações também têm 8
24d5ac3d36SDaniel Pereiracaracteres. Há movimentos heréticos que tentam fazer com que as indentações
25d5ac3d36SDaniel Pereiratenham 4 (ou até 2!) caracteres de profundidade, e isso é semelhante a
26d5ac3d36SDaniel Pereiratentar definir o valor de PI como 3.
27d5ac3d36SDaniel Pereira
28d5ac3d36SDaniel PereiraJustificativa: A ideia central da indentação é definir claramente onde um
29d5ac3d36SDaniel Pereirabloco de controle começa e termina. Especialmente quando você esteve olhando
30d5ac3d36SDaniel Pereirapara a tela por 20 horas seguidas, você vai achar muito mais fácil ver como
31d5ac3d36SDaniel Pereiraa indentação funciona se ela for mais ampla.
32d5ac3d36SDaniel Pereira
33d5ac3d36SDaniel PereiraAgora, algumas pessoas afirmarão que ter indentações de 8 caracteres faz
34d5ac3d36SDaniel Pereirao código se deslocar demais para a direita e dificultam a leitura em um
35d5ac3d36SDaniel Pereiraterminal de 80 caracteres. A resposta é que, se você precisar de mais de 3
36d5ac3d36SDaniel Pereiraníveis de indentação, você já está em apuros de qualquer forma, e deve
37d5ac3d36SDaniel Pereiracorrigir seu programa.
38d5ac3d36SDaniel Pereira
39d5ac3d36SDaniel PereiraEm resumo, indentações de 8 caracteres deixam as coisas mais fáceis de ler, e
40d5ac3d36SDaniel Pereiratêm o benefício adicional de avisar quando você está aninhando suas funções
41d5ac3d36SDaniel Pereiraem excesso. Atenda a esse aviso.
42d5ac3d36SDaniel Pereira
43d5ac3d36SDaniel PereiraA maneira preferida de aliviar vários níveis de indentação em uma instrução
44d5ac3d36SDaniel Pereira``switch`` é alinhar o ``switch`` e seus rótulos subordinados ``case`` na
45d5ac3d36SDaniel Pereiramesma coluna, em vez de indentar duplamente os rótulos ``case``. Por exemplo:
46d5ac3d36SDaniel Pereira
47d5ac3d36SDaniel Pereira.. code-block:: c
48d5ac3d36SDaniel Pereira
49d5ac3d36SDaniel Pereira	switch (suffix) {
50d5ac3d36SDaniel Pereira	case 'G':
51d5ac3d36SDaniel Pereira	case 'g':
52d5ac3d36SDaniel Pereira		mem <<= 30;
53d5ac3d36SDaniel Pereira		break;
54d5ac3d36SDaniel Pereira	case 'M':
55d5ac3d36SDaniel Pereira	case 'm':
56d5ac3d36SDaniel Pereira		mem <<= 20;
57d5ac3d36SDaniel Pereira		break;
58d5ac3d36SDaniel Pereira	case 'K':
59d5ac3d36SDaniel Pereira	case 'k':
60d5ac3d36SDaniel Pereira		mem <<= 10;
61d5ac3d36SDaniel Pereira		fallthrough;
62d5ac3d36SDaniel Pereira	default:
63d5ac3d36SDaniel Pereira		break;
64d5ac3d36SDaniel Pereira	}
65d5ac3d36SDaniel Pereira
66d5ac3d36SDaniel PereiraNão coloque múltiplas instruções em uma única linha, a menos que você tenha
67d5ac3d36SDaniel Pereiraalgo para esconder:
68d5ac3d36SDaniel Pereira
69d5ac3d36SDaniel Pereira.. code-block:: c
70d5ac3d36SDaniel Pereira
71d5ac3d36SDaniel Pereira	if (condition) do_this;
72d5ac3d36SDaniel Pereira	  do_something_everytime;
73d5ac3d36SDaniel Pereira
74d5ac3d36SDaniel PereiraNão use vírgulas para evitar usar chaves:
75d5ac3d36SDaniel Pereira
76d5ac3d36SDaniel Pereira.. code-block:: c
77d5ac3d36SDaniel Pereira
78d5ac3d36SDaniel Pereira	if (condition)
79d5ac3d36SDaniel Pereira		do_this(), do_that();
80d5ac3d36SDaniel Pereira
81d5ac3d36SDaniel PereiraSempre use chaves para múltiplas instruções:
82d5ac3d36SDaniel Pereira
83d5ac3d36SDaniel Pereira.. code-block:: c
84d5ac3d36SDaniel Pereira
85d5ac3d36SDaniel Pereira	if (condition) {
86d5ac3d36SDaniel Pereira		do_this();
87d5ac3d36SDaniel Pereira		do_that();
88d5ac3d36SDaniel Pereira	}
89d5ac3d36SDaniel Pereira
90d5ac3d36SDaniel PereiraTambém não coloque múltiplas atribuições em uma única linha. O estilo de
91d5ac3d36SDaniel Pereiracodificação do kernel é extremamente simples. Evite expressões complicadas.
92d5ac3d36SDaniel Pereira
93d5ac3d36SDaniel Pereira
94d5ac3d36SDaniel PereiraFora de comentários, documentação e, exceto em Kconfig, espaços nunca são
95d5ac3d36SDaniel Pereirausados para indentação, e o exemplo acima foi deliberadamente quebrado.
96d5ac3d36SDaniel Pereira
97d5ac3d36SDaniel PereiraObtenha um editor decente e não deixe espaços em branco no final das linhas.
98d5ac3d36SDaniel Pereira
99d5ac3d36SDaniel Pereira
100d5ac3d36SDaniel Pereira2) Quebrando linhas longas e strings
101d5ac3d36SDaniel Pereira------------------------------------
102d5ac3d36SDaniel Pereira
103d5ac3d36SDaniel PereiraO estilo de codificação trata principalmente da legibilidade e da
104d5ac3d36SDaniel Pereiramanutenibilidade usando ferramentas comumente disponíveis.
105d5ac3d36SDaniel Pereira
106d5ac3d36SDaniel PereiraO limite preferido para o comprimento de uma única linha é de 80 colunas.
107d5ac3d36SDaniel Pereira
108d5ac3d36SDaniel PereiraInstruções com mais de 80 colunas devem ser quebradas em partes sensatas,
109d5ac3d36SDaniel Pereiraa menos que exceder 80 colunas aumente significativamente a legibilidade e
110d5ac3d36SDaniel Pereiranão esconda informações.
111d5ac3d36SDaniel Pereira
112d5ac3d36SDaniel PereiraOs descendentes são sempre substancialmente mais curtos do que o pai e são
113d5ac3d36SDaniel Pereiracolocados substancialmente à direita. Um estilo muito usado é alinhar os
114d5ac3d36SDaniel Pereiradescendentes ao parêntese de abertura de uma função.
115d5ac3d36SDaniel Pereira
116d5ac3d36SDaniel PereiraEssas mesmas regras são aplicadas aos cabeçalhos de função com uma lista de
117d5ac3d36SDaniel Pereiraargumentos longa.
118d5ac3d36SDaniel Pereira
119d5ac3d36SDaniel PereiraNo entanto, nunca quebre strings visíveis ao usuário, como mensagens
120d5ac3d36SDaniel Pereira``printk``, porque isso prejudica a capacidade de fazer ``grep`` nelas.
121d5ac3d36SDaniel Pereira
122d5ac3d36SDaniel Pereira
123d5ac3d36SDaniel Pereira3) Posicionamento de chaves e espaços
124d5ac3d36SDaniel Pereira-------------------------------------
125d5ac3d36SDaniel Pereira
126d5ac3d36SDaniel PereiraA outra questão que sempre surge no estilo em C é o posicionamento das
127d5ac3d36SDaniel Pereirachaves. Ao contrário do tamanho da indentação, há poucos motivos técnicos
128d5ac3d36SDaniel Pereirapara escolher uma estratégia de posicionamento em vez de outra, mas a forma
129d5ac3d36SDaniel Pereirapreferida, como nos mostraram os profetas Kernighan e Ritchie, é colocar a
130d5ac3d36SDaniel Pereirachave de abertura no final da linha e a chave de fechamento no início, assim:
131d5ac3d36SDaniel Pereira
132d5ac3d36SDaniel Pereira.. code-block:: c
133d5ac3d36SDaniel Pereira
134d5ac3d36SDaniel Pereira	if (x is true) {
135d5ac3d36SDaniel Pereira		we do y
136d5ac3d36SDaniel Pereira	}
137d5ac3d36SDaniel Pereira
138d5ac3d36SDaniel PereiraIsso se aplica a todos os blocos de instruções que não sejam funções (if,
139d5ac3d36SDaniel Pereiraswitch, for, while, do). Por exemplo:
140d5ac3d36SDaniel Pereira
141d5ac3d36SDaniel Pereira.. code-block:: c
142d5ac3d36SDaniel Pereira
143d5ac3d36SDaniel Pereira	switch (action) {
144d5ac3d36SDaniel Pereira	case KOBJ_ADD:
145d5ac3d36SDaniel Pereira		return "add";
146d5ac3d36SDaniel Pereira	case KOBJ_REMOVE:
147d5ac3d36SDaniel Pereira		return "remove";
148d5ac3d36SDaniel Pereira	case KOBJ_CHANGE:
149d5ac3d36SDaniel Pereira		return "change";
150d5ac3d36SDaniel Pereira	default:
151d5ac3d36SDaniel Pereira		return NULL;
152d5ac3d36SDaniel Pereira	}
153d5ac3d36SDaniel Pereira
154d5ac3d36SDaniel PereiraNo entanto, há um caso especial: as funções, que têm a chave de abertura no
155d5ac3d36SDaniel Pereirainício da linha seguinte, assim:
156d5ac3d36SDaniel Pereira
157d5ac3d36SDaniel Pereira.. code-block:: c
158d5ac3d36SDaniel Pereira
159d5ac3d36SDaniel Pereira	int function(int x)
160d5ac3d36SDaniel Pereira	{
161d5ac3d36SDaniel Pereira		body of function
162d5ac3d36SDaniel Pereira	}
163d5ac3d36SDaniel Pereira
164d5ac3d36SDaniel PereiraPessoas heréticas por todo o mundo afirmaram que essa inconsistência é ...
165d5ac3d36SDaniel Pereirabem ... inconsistente, mas todas as pessoas de bom senso sabem que (a) K&R
166d5ac3d36SDaniel Pereiraestão **corretos** e (b) K&R estão certos. Além disso, as funções são
167d5ac3d36SDaniel Pereiraespeciais de qualquer forma (você não pode aninhá-las em C).
168d5ac3d36SDaniel Pereira
169d5ac3d36SDaniel PereiraObserve que a chave de fechamento fica vazia em uma linha própria, **exceto**
170d5ac3d36SDaniel Pereiranos casos em que ela é seguida por uma continuação da mesma instrução, ou
171d5ac3d36SDaniel Pereiraseja, um ``while`` em um do-statement ou um ``else`` em um if-statement, como
172d5ac3d36SDaniel Pereiraneste exemplo:
173d5ac3d36SDaniel Pereira
174d5ac3d36SDaniel Pereira.. code-block:: c
175d5ac3d36SDaniel Pereira
176d5ac3d36SDaniel Pereira	do {
177d5ac3d36SDaniel Pereira		body of do-loop
178d5ac3d36SDaniel Pereira	} while (condition);
179d5ac3d36SDaniel Pereira
180d5ac3d36SDaniel Pereirae
181d5ac3d36SDaniel Pereira
182d5ac3d36SDaniel Pereira.. code-block:: c
183d5ac3d36SDaniel Pereira
184d5ac3d36SDaniel Pereira	if (x == y) {
185d5ac3d36SDaniel Pereira		..
186d5ac3d36SDaniel Pereira	} else if (x > y) {
187d5ac3d36SDaniel Pereira		...
188d5ac3d36SDaniel Pereira	} else {
189d5ac3d36SDaniel Pereira		....
190d5ac3d36SDaniel Pereira	}
191d5ac3d36SDaniel Pereira
192d5ac3d36SDaniel PereiraJustificativa: K&R.
193d5ac3d36SDaniel Pereira
194d5ac3d36SDaniel PereiraAlém disso, observe que esse posicionamento de chaves também minimiza o
195d5ac3d36SDaniel Pereiranúmero de linhas vazias (ou quase vazias), sem qualquer perda de
196d5ac3d36SDaniel Pereiralegibilidade. Assim, como o suprimento de linhas novas na sua tela não é um
197d5ac3d36SDaniel Pereirarecurso renovável (pense em telas de terminal de 25 linhas), você tem mais
198d5ac3d36SDaniel Pereiralinhas vazias para colocar comentários.
199d5ac3d36SDaniel Pereira
200d5ac3d36SDaniel PereiraNão use chaves desnecessariamente quando uma única instrução basta.
201d5ac3d36SDaniel Pereira
202d5ac3d36SDaniel Pereira.. code-block:: c
203d5ac3d36SDaniel Pereira
204d5ac3d36SDaniel Pereira	if (condition)
205d5ac3d36SDaniel Pereira		action();
206d5ac3d36SDaniel Pereira
207d5ac3d36SDaniel Pereirae
208d5ac3d36SDaniel Pereira
209d5ac3d36SDaniel Pereira.. code-block:: c
210d5ac3d36SDaniel Pereira
211d5ac3d36SDaniel Pereira	if (condition)
212d5ac3d36SDaniel Pereira		do_this();
213d5ac3d36SDaniel Pereira	else
214d5ac3d36SDaniel Pereira		do_that();
215d5ac3d36SDaniel Pereira
216d5ac3d36SDaniel PereiraIsso não se aplica se apenas um ramo de uma instrução condicional for uma
217d5ac3d36SDaniel Pereiraúnica instrução; nesse último caso, use chaves em ambos os ramos:
218d5ac3d36SDaniel Pereira
219d5ac3d36SDaniel Pereira.. code-block:: c
220d5ac3d36SDaniel Pereira
221d5ac3d36SDaniel Pereira	if (condition) {
222d5ac3d36SDaniel Pereira		do_this();
223d5ac3d36SDaniel Pereira		do_that();
224d5ac3d36SDaniel Pereira	} else {
225d5ac3d36SDaniel Pereira		otherwise();
226d5ac3d36SDaniel Pereira	}
227d5ac3d36SDaniel Pereira
228d5ac3d36SDaniel PereiraAlém disso, use chaves quando um laço contiver mais de uma instrução simples:
229d5ac3d36SDaniel Pereira
230d5ac3d36SDaniel Pereira.. code-block:: c
231d5ac3d36SDaniel Pereira
232d5ac3d36SDaniel Pereira	while (condition) {
233d5ac3d36SDaniel Pereira		if (test)
234d5ac3d36SDaniel Pereira			do_something();
235d5ac3d36SDaniel Pereira	}
236d5ac3d36SDaniel Pereira
237d5ac3d36SDaniel Pereira3.1) Espaços
238d5ac3d36SDaniel Pereira************
239d5ac3d36SDaniel Pereira
240d5ac3d36SDaniel PereiraO estilo do kernel Linux para o uso de espaços depende (em grande parte) do
241d5ac3d36SDaniel Pereirauso de função versus palavra-chave. Use um espaço após (a maioria das)
242d5ac3d36SDaniel Pereirapalavras-chave. As exceções notáveis são ``sizeof``, ``typeof``, ``alignof`` e
243d5ac3d36SDaniel Pereira``__attribute__``, que parecem um pouco com funções (e geralmente são usadas
244d5ac3d36SDaniel Pereiracom parênteses no Linux, embora não sejam obrigatórias na linguagem, como em:
245d5ac3d36SDaniel Pereira``sizeof info`` depois que ``struct fileinfo info;`` é declarado).
246d5ac3d36SDaniel Pereira
247d5ac3d36SDaniel PereiraEntão use um espaço após estas palavras-chave::
248d5ac3d36SDaniel Pereira
249d5ac3d36SDaniel Pereira	if, switch, case, for, do, while
250d5ac3d36SDaniel Pereira
251d5ac3d36SDaniel Pereiramas não com ``sizeof``, ``typeof``, ``alignof`` ou ``__attribute__``. Por
252d5ac3d36SDaniel Pereiraexemplo,
253d5ac3d36SDaniel Pereira
254d5ac3d36SDaniel Pereira.. code-block:: c
255d5ac3d36SDaniel Pereira
256d5ac3d36SDaniel Pereira
257d5ac3d36SDaniel Pereira	s = sizeof(struct file);
258d5ac3d36SDaniel Pereira
259d5ac3d36SDaniel PereiraNão adicione espaços ao redor (dentro) de expressões entre parênteses. Este
260d5ac3d36SDaniel Pereiraexemplo é **ruim**:
261d5ac3d36SDaniel Pereira
262d5ac3d36SDaniel Pereira.. code-block:: c
263d5ac3d36SDaniel Pereira
264d5ac3d36SDaniel Pereira
265d5ac3d36SDaniel Pereira	s = sizeof( struct file );
266d5ac3d36SDaniel Pereira
267d5ac3d36SDaniel PereiraAo declarar dados de ponteiro ou uma função que retorna um tipo de ponteiro, o
268d5ac3d36SDaniel Pereirauso preferido de ``*`` fica adjacente ao nome dos dados ou ao nome da função e
269d5ac3d36SDaniel Pereiranão adjacente ao nome do tipo. Exemplos:
270d5ac3d36SDaniel Pereira
271d5ac3d36SDaniel Pereira.. code-block:: c
272d5ac3d36SDaniel Pereira
273d5ac3d36SDaniel Pereira
274d5ac3d36SDaniel Pereira	char *linux_banner;
275d5ac3d36SDaniel Pereira	unsigned long long memparse(char *ptr, char **retptr);
276d5ac3d36SDaniel Pereira	char *match_strdup(substring_t *s);
277d5ac3d36SDaniel Pereira
278d5ac3d36SDaniel PereiraUse um espaço em volta (de cada lado) da maioria dos operadores binários e
279d5ac3d36SDaniel Pereiraternários, como qualquer um destes::
280d5ac3d36SDaniel Pereira
281d5ac3d36SDaniel Pereira	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :
282d5ac3d36SDaniel Pereira
283d5ac3d36SDaniel Pereiramas sem espaço após operadores unários::
284d5ac3d36SDaniel Pereira
285d5ac3d36SDaniel Pereira	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined
286d5ac3d36SDaniel Pereira
287d5ac3d36SDaniel Pereirasem espaço antes dos operadores unários pós-fixados de incremento e
288d5ac3d36SDaniel Pereiradecremento::
289d5ac3d36SDaniel Pereira
290d5ac3d36SDaniel Pereira	++  --
291d5ac3d36SDaniel Pereira
292d5ac3d36SDaniel Pereirasem espaço após os operadores unários prefixados de incremento e
293d5ac3d36SDaniel Pereiradecremento::
294d5ac3d36SDaniel Pereira
295d5ac3d36SDaniel Pereira	++  --
296d5ac3d36SDaniel Pereira
297d5ac3d36SDaniel Pereirae sem espaço ao redor dos operadores de membro de estrutura ``.`` e ``->``.
298d5ac3d36SDaniel Pereira
299d5ac3d36SDaniel PereiraNão deixe espaços em branco no final das linhas. Alguns editores com
300d5ac3d36SDaniel Pereiraindentação ``inteligente`` inserem espaços no início das novas linhas conforme
301d5ac3d36SDaniel Pereiraapropriado, para que você possa começar a digitar a próxima linha de código
302d5ac3d36SDaniel Pereiraimediatamente. No entanto, alguns desses editores não removem o espaço em
303d5ac3d36SDaniel Pereirabranco se você acabar não colocando uma linha de código ali, como quando deixa
304d5ac3d36SDaniel Pereirauma linha em branco. Como resultado, você termina com linhas contendo espaço
305d5ac3d36SDaniel Pereiraem branco no final.
306d5ac3d36SDaniel Pereira
307d5ac3d36SDaniel PereiraO Git avisará você sobre patches que introduzem espaço em branco no final e
308d5ac3d36SDaniel Pereirapode remover esse espaço automaticamente para você; entretanto, se você
309d5ac3d36SDaniel Pereiraaplicar uma série de patches, isso pode fazer com que patches posteriores da
310d5ac3d36SDaniel Pereirasérie falhem ao alterar suas linhas de contexto.
311d5ac3d36SDaniel Pereira
312d5ac3d36SDaniel Pereira
313d5ac3d36SDaniel Pereira4) Nomeação
314d5ac3d36SDaniel Pereira-----------
315d5ac3d36SDaniel Pereira
316d5ac3d36SDaniel PereiraC é uma linguagem espartana, e suas convenções de nomenclatura devem seguir o
317d5ac3d36SDaniel Pereiramesmo caminho. Ao contrário dos programadores em Modula-2 e Pascal, os
318d5ac3d36SDaniel Pereiraprogramadores em C não usam nomes bonitinhos como ThisVariableIsATemporaryCounter.
319d5ac3d36SDaniel PereiraUm programador em C chamaria essa variável de ``tmp``, o que é muito mais fácil
320d5ac3d36SDaniel Pereirade escrever e não é menos fácil de entender.
321d5ac3d36SDaniel Pereira
322d5ac3d36SDaniel PereiraENTRETANTO, embora nomes em camelCase sejam desencorajados, nomes descritivos
323d5ac3d36SDaniel Pereirapara variáveis globais são essenciais. Chamar uma função global de ``foo`` é
324d5ac3d36SDaniel Pereiraum crime.
325d5ac3d36SDaniel Pereira
326d5ac3d36SDaniel PereiraVariáveis GLOBAIS (a serem usadas somente se você **realmente** precisar) devem
327d5ac3d36SDaniel Pereirater nomes descritivos, assim como as funções globais. Se você tiver uma função
328d5ac3d36SDaniel Pereiraque conta o número de usuários ativos, você deve chamá-la de
329d5ac3d36SDaniel Pereira``count_active_users()`` ou algo parecido; você **não** deve chamá-la de
330d5ac3d36SDaniel Pereira``cntusr()``.
331d5ac3d36SDaniel Pereira
332d5ac3d36SDaniel PereiraCodificar o tipo de uma função no nome (a chamada notação Húngara) é absurdo -
333d5ac3d36SDaniel Pereirao compilador conhece os tipos de qualquer forma e pode verificar isso, e isso
334d5ac3d36SDaniel Pereirasó confunde o programador.
335d5ac3d36SDaniel Pereira
336d5ac3d36SDaniel PereiraNomes de variáveis locais devem ser curtos e diretos. Se você tiver algum
337d5ac3d36SDaniel Pereiracontador inteiro aleatório de loop, provavelmente deve ser chamado de ``i``.
338d5ac3d36SDaniel PereiraChamá-lo de ``loop_counter`` é improdutivo, se não houver chance de ser mal
339d5ac3d36SDaniel Pereirainterpretado. Da mesma forma, ``tmp`` pode ser praticamente qualquer tipo de
340d5ac3d36SDaniel Pereiravariável usada para manter um valor temporário.
341d5ac3d36SDaniel Pereira
342d5ac3d36SDaniel PereiraSe você tem medo de misturar os nomes de variáveis locais, você tem outro
343d5ac3d36SDaniel Pereiraproblema, chamado síndrome de desequilíbrio de hormônio de crescimento da
344d5ac3d36SDaniel Pereirafunção. Veja o capítulo 6 (Funções).
345d5ac3d36SDaniel Pereira
346d5ac3d36SDaniel PereiraPara nomes de símbolos e documentação, evite introduzir o uso novo de
347d5ac3d36SDaniel Pereira'master / slave' (ou 'slave' independente de 'master') e 'blacklist /
348d5ac3d36SDaniel Pereirawhitelist'.
349d5ac3d36SDaniel Pereira
350d5ac3d36SDaniel PereiraSubstituições recomendadas para 'master / slave' são:
351d5ac3d36SDaniel Pereira    '{primary,main} / {secondary,replica,subordinate}'
352d5ac3d36SDaniel Pereira    '{initiator,requester} / {target,responder}'
353d5ac3d36SDaniel Pereira    '{controller,host} / {device,worker,proxy}'
354d5ac3d36SDaniel Pereira    'leader / follower'
355d5ac3d36SDaniel Pereira    'director / performer'
356d5ac3d36SDaniel Pereira
357d5ac3d36SDaniel PereiraSubstituições recomendadas para 'blacklist/whitelist' são:
358d5ac3d36SDaniel Pereira    'denylist / allowlist'
359d5ac3d36SDaniel Pereira    'blocklist / passlist'
360d5ac3d36SDaniel Pereira
361d5ac3d36SDaniel PereiraExceções para introduzir novos usos são manter uma ABI/API do espaço do
362d5ac3d36SDaniel Pereirausuário, ou ao atualizar código para um hardware ou especificação de
363d5ac3d36SDaniel Pereiraprotocolo existente (a partir de 2020) que exija esses termos. Para novas
364d5ac3d36SDaniel Pereiraespecificações, traduza o uso da terminologia na especificação para o padrão
365d5ac3d36SDaniel Pereirade codificação do kernel quando possível.
366d5ac3d36SDaniel Pereira
367d5ac3d36SDaniel Pereira5) Tipos definidos (typedefs)
368d5ac3d36SDaniel Pereira-----------------------------
369d5ac3d36SDaniel Pereira
370d5ac3d36SDaniel PereiraPor favor, não use coisas como ``vps_t``.
371d5ac3d36SDaniel PereiraÉ um **erro** usar ``typedef`` para estruturas e ponteiros. Quando você vê
372d5ac3d36SDaniel Pereira
373d5ac3d36SDaniel Pereira.. code-block:: c
374d5ac3d36SDaniel Pereira
375d5ac3d36SDaniel Pereira
376d5ac3d36SDaniel Pereira	vps_t a;
377d5ac3d36SDaniel Pereira
378d5ac3d36SDaniel Pereirano código-fonte, o que isso significa?
379d5ac3d36SDaniel PereiraEm contraste, se diz
380d5ac3d36SDaniel Pereira
381d5ac3d36SDaniel Pereira.. code-block:: c
382d5ac3d36SDaniel Pereira
383d5ac3d36SDaniel Pereira	struct virtual_container *a;
384d5ac3d36SDaniel Pereira
385d5ac3d36SDaniel Pereiravocê consegue dizer o que ``a`` é.
386d5ac3d36SDaniel Pereira
387d5ac3d36SDaniel PereiraMuitas pessoas pensam que ``typedef``s ``ajudam na legibilidade``. Não é bem
388d5ac3d36SDaniel Pereiraassim. Eles são úteis apenas para:
389d5ac3d36SDaniel Pereira
390d5ac3d36SDaniel Pereira (a) objetos totalmente opacos (onde o ``typedef`` é usado ativamente para
391d5ac3d36SDaniel Pereira     **ocultar** o que o objeto é).
392d5ac3d36SDaniel Pereira
393d5ac3d36SDaniel Pereira     Exemplo: ``pte_t`` etc. Objetos opacos que você só pode acessar usando
394d5ac3d36SDaniel Pereira     as funções de acesso apropriadas.
395d5ac3d36SDaniel Pereira
396d5ac3d36SDaniel Pereira     .. note::
397d5ac3d36SDaniel Pereira
398d5ac3d36SDaniel Pereira       Opacidade e ``funções de acesso`` não são boas em si mesmas.
399d5ac3d36SDaniel Pereira       A razão pela qual as temos para coisas como ``pte_t`` etc. é que
400d5ac3d36SDaniel Pereira       realmente existe absolutamente **zero** informação acessível de forma portátil
401d5ac3d36SDaniel Pereira       ali.
402d5ac3d36SDaniel Pereira
403d5ac3d36SDaniel Pereira (b) tipos inteiros claros, em que a abstração **ajuda** a evitar confusão
404d5ac3d36SDaniel Pereira     sobre se é ``int`` ou ``long``.
405d5ac3d36SDaniel Pereira
406d5ac3d36SDaniel Pereira     ``u8/u16/u32`` são typedefs perfeitamente aceitáveis, embora se
407d5ac3d36SDaniel Pereira     encaixem melhor na categoria (d) do que aqui.
408d5ac3d36SDaniel Pereira
409d5ac3d36SDaniel Pereira     .. note::
410d5ac3d36SDaniel Pereira
411d5ac3d36SDaniel Pereira       Novamente - precisa haver uma **razão** para isso. Se algo é
412d5ac3d36SDaniel Pereira       ``unsigned long``, não há motivo para fazer
413d5ac3d36SDaniel Pereira
414d5ac3d36SDaniel Pereira	typedef unsigned long myflags_t;
415d5ac3d36SDaniel Pereira
416d5ac3d36SDaniel Pereira     mas se houver uma razão clara para que em certas circunstâncias possa
417d5ac3d36SDaniel Pereira     ser ``unsigned int`` e em outras configurações possa ser ``unsigned
418d5ac3d36SDaniel Pereira     long``, então, claro, use um ``typedef``.
419d5ac3d36SDaniel Pereira
420d5ac3d36SDaniel Pereira (c) quando você usa ``sparse`` para criar literalmente um **novo** tipo para
421d5ac3d36SDaniel Pereira     verificação de tipos.
422d5ac3d36SDaniel Pereira
423d5ac3d36SDaniel Pereira (d) novos tipos idênticos aos tipos padrão do C99, em certas
424d5ac3d36SDaniel Pereira     circunstâncias excepcionais.
425d5ac3d36SDaniel Pereira
426d5ac3d36SDaniel Pereira     Embora levasse apenas um curto período para os olhos e o cérebro se
427d5ac3d36SDaniel Pereira     acostumarem aos tipos padrão como ``uint32_t``, algumas pessoas ainda
428d5ac3d36SDaniel Pereira     se opõem ao seu uso.
429d5ac3d36SDaniel Pereira
430d5ac3d36SDaniel Pereira     Portanto, os tipos específicos do Linux ``u8/u16/u32/u64`` e seus
431d5ac3d36SDaniel Pereira     equivalentes assinados, que são idênticos aos tipos padrão, são
432d5ac3d36SDaniel Pereira     permitidos -- embora não sejam obrigatórios em código novo seu.
433d5ac3d36SDaniel Pereira
434d5ac3d36SDaniel Pereira     Ao editar código existente que já usa um ou outro conjunto de tipos, você
435d5ac3d36SDaniel Pereira     deve seguir as escolhas existentes nesse código.
436d5ac3d36SDaniel Pereira
437d5ac3d36SDaniel Pereira (e) tipos seguros para uso em espaço do usuário.
438d5ac3d36SDaniel Pereira
439d5ac3d36SDaniel Pereira     Em certas estruturas visíveis ao espaço do usuário, não podemos exigir
440d5ac3d36SDaniel Pereira     tipos C99 nem usar a forma ``u32`` acima. Portanto, usamos ``__u32`` e
441d5ac3d36SDaniel Pereira     tipos semelhantes em todas as estruturas compartilhadas com o espaço do
442d5ac3d36SDaniel Pereira     usuário.
443d5ac3d36SDaniel Pereira
444d5ac3d36SDaniel PereiraPode haver outros casos também, mas a regra básica deve ser: NUNCA use um
445d5ac3d36SDaniel Pereira``typedef`` a menos que você consiga encaixar claramente em uma dessas regras.
446d5ac3d36SDaniel Pereira
447d5ac3d36SDaniel PereiraEm geral, um ponteiro, ou uma estrutura com elementos que podem ser acessados
448d5ac3d36SDaniel Pereiradiretamente, **nunca** deve ser um ``typedef``.
449d5ac3d36SDaniel Pereira
450d5ac3d36SDaniel Pereira
451d5ac3d36SDaniel Pereira6) Funções
452d5ac3d36SDaniel Pereira----------
453d5ac3d36SDaniel Pereira
454d5ac3d36SDaniel PereiraAs funções devem ser curtas e diretas, e fazer apenas uma coisa. Elas devem
455d5ac3d36SDaniel Pereiracaber em uma ou duas telas de texto (o tamanho de tela ISO/ANSI é 80x24,
456d5ac3d36SDaniel Pereiracomo todos sabem), e fazer uma coisa e fazê-la bem.
457d5ac3d36SDaniel Pereira
458d5ac3d36SDaniel PereiraO comprimento máximo de uma função é inversamente proporcional à complexidade
459d5ac3d36SDaniel Pereirae ao nível de indentação dessa função. Então, se você tiver uma função
460d5ac3d36SDaniel Pereiraconceitualmente simples que seja apenas uma longa (mas simples) instrução
461d5ac3d36SDaniel Pereira``switch``, em que você precisa fazer várias pequenas coisas para muitos casos
462d5ac3d36SDaniel Pereiradiferentes, é aceitável ter uma função mais longa.
463d5ac3d36SDaniel Pereira
464d5ac3d36SDaniel PereiraNo entanto, se você tiver uma função complexa e suspeitar que um estudante
465d5ac3d36SDaniel Pereirado primeiro ano do ensino médio, menos talentoso, talvez nem entenda do que
466d5ac3d36SDaniel Pereirase trata a função, você deve obedecer aos limites máximos ainda mais de
467d5ac3d36SDaniel Pereiraperto. Use funções auxiliares com nomes descritivos (você pode pedir ao
468d5ac3d36SDaniel Pereiracompilador para incorporá-las em linha se achar que é crítico para o
469d5ac3d36SDaniel Pereiradesempenho, e provavelmente ele fará um trabalho melhor do que você faria).
470d5ac3d36SDaniel Pereira
471d5ac3d36SDaniel PereiraOutra medida da função é o número de variáveis locais. Elas não devem exceder
472d5ac3d36SDaniel Pereira5-10, ou algo está errado. Reflita sobre a função e divida em partes menores.
473d5ac3d36SDaniel PereiraUm cérebro humano geralmente consegue rastrear facilmente cerca de 7 coisas
474d5ac3d36SDaniel Pereiradiferentes; qualquer quantidade acima disso o confunde. Você sabe que é
475d5ac3d36SDaniel Pereirabrilhante, mas talvez queira entender o que fez daqui a 2 semanas.
476d5ac3d36SDaniel Pereira
477d5ac3d36SDaniel PereiraNos arquivos de código-fonte, separe as funções com uma linha em branco. Se a
478d5ac3d36SDaniel Pereirafunção for exportada, a macro **EXPORT** para ela deve seguir imediatamente
479d5ac3d36SDaniel Pereiradepois da linha da chave de fechamento da função. Por exemplo:
480d5ac3d36SDaniel Pereira
481d5ac3d36SDaniel Pereira.. code-block:: c
482d5ac3d36SDaniel Pereira
483d5ac3d36SDaniel Pereira	int system_is_up(void)
484d5ac3d36SDaniel Pereira	{
485d5ac3d36SDaniel Pereira		return system_state == SYSTEM_RUNNING;
486d5ac3d36SDaniel Pereira	}
487d5ac3d36SDaniel Pereira	EXPORT_SYMBOL(system_is_up);
488d5ac3d36SDaniel Pereira
489d5ac3d36SDaniel Pereira6.1) Protótipos de função
490d5ac3d36SDaniel Pereira*************************
491d5ac3d36SDaniel Pereira
492d5ac3d36SDaniel PereiraNos protótipos de função, inclua nomes de parâmetros junto com seus tipos de
493d5ac3d36SDaniel Pereiradados. Embora isso não seja obrigatório pela linguagem C, é preferido no Linux
494d5ac3d36SDaniel Pereiraporque é uma maneira simples de adicionar informações valiosas para o leitor.
495d5ac3d36SDaniel Pereira
496d5ac3d36SDaniel PereiraNão use a palavra-chave ``extern`` em declarações de função, pois isso torna
497d5ac3d36SDaniel Pereiraas linhas mais longas e não é estritamente necessário.
498d5ac3d36SDaniel Pereira
499d5ac3d36SDaniel PereiraAo escrever protótipos de função, por favor mantenha a `ordem dos elementos
500d5ac3d36SDaniel Pereiraregular <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_.
501d5ac3d36SDaniel PereiraPor exemplo, usando este exemplo de declaração de função::
502d5ac3d36SDaniel Pereira
503d5ac3d36SDaniel Pereira __init void * __must_check action(enum magic value, size_t size, u8 count,
504d5ac3d36SDaniel Pereira				   char *fmt, ...) __printf(4, 5) __malloc;
505d5ac3d36SDaniel Pereira
506d5ac3d36SDaniel PereiraA ordem preferida dos elementos para um protótipo de função é:
507d5ac3d36SDaniel Pereira
508d5ac3d36SDaniel Pereira- classe de armazenamento (abaixo, ``static __always_inline``, observando que
509d5ac3d36SDaniel Pereira  ``__always_inline`` é tecnicamente um atributo, mas é tratado como ``inline``)
510d5ac3d36SDaniel Pereira- atributos de classe de armazenamento (aqui, ``__init`` -- ou seja,
511d5ac3d36SDaniel Pereira  declarações de seção, mas também coisas como ``__cold``)
512d5ac3d36SDaniel Pereira- tipo de retorno (aqui, ``void *``)
513d5ac3d36SDaniel Pereira- atributos do tipo de retorno (aqui, ``__must_check``)
514d5ac3d36SDaniel Pereira- nome da função (aqui, ``action``)
515d5ac3d36SDaniel Pereira- parâmetros da função (aqui, ``(enum magic value, size_t size, u8 count,
516d5ac3d36SDaniel Pereira  char *fmt, ...)``, observando que os nomes dos parâmetros devem sempre ser
517d5ac3d36SDaniel Pereira  incluídos)
518d5ac3d36SDaniel Pereira- atributos dos parâmetros da função (aqui, ``__printf(4, 5)``)
519d5ac3d36SDaniel Pereira- atributos de comportamento da função (aqui, ``__malloc``)
520d5ac3d36SDaniel Pereira
521d5ac3d36SDaniel PereiraObserve que, para uma **definição** de função (ou seja, o corpo real da
522d5ac3d36SDaniel Pereirafunção), o compilador não permite atributos de parâmetro da função depois dos
523d5ac3d36SDaniel Pereiraparâmetros da função. Nesses casos, eles devem vir depois dos atributos da
524d5ac3d36SDaniel Pereiraclasse de armazenamento (por exemplo, observe a posição alterada de
525d5ac3d36SDaniel Pereira``__printf(4, 5)`` abaixo, em comparação com o exemplo de **declaração**
526d5ac3d36SDaniel Pereiraacima)::
527d5ac3d36SDaniel Pereira
528d5ac3d36SDaniel Pereira static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
529d5ac3d36SDaniel Pereira		size_t size, u8 count, char *fmt, ...) __malloc
530d5ac3d36SDaniel Pereira {
531d5ac3d36SDaniel Pereira	...
532d5ac3d36SDaniel Pereira }
533d5ac3d36SDaniel Pereira
534d5ac3d36SDaniel Pereira7) Saída centralizada de funções
535d5ac3d36SDaniel Pereira--------------------------------
536d5ac3d36SDaniel Pereira
537d5ac3d36SDaniel PereiraEmbora seja depreciado por algumas pessoas, o equivalente da instrução
538d5ac3d36SDaniel Pereira``goto`` é usado com frequência pelos compiladores na forma da instrução de
539d5ac3d36SDaniel Pereirasalto incondicional.
540d5ac3d36SDaniel Pereira
541d5ac3d36SDaniel PereiraA instrução ``goto`` é útil quando uma função sai de vários pontos e é
542d5ac3d36SDaniel Pereiranecessária alguma tarefa comum, como limpeza. Se não for necessária nenhuma
543d5ac3d36SDaniel Pereiralimpeza, basta retornar diretamente.
544d5ac3d36SDaniel Pereira
545d5ac3d36SDaniel PereiraEscolha nomes de rótulos que indiquem o que o ``goto`` faz ou por que ele
546d5ac3d36SDaniel Pereiraexiste. Um exemplo de nome bom poderia ser ``out_free_buffer:`` se o goto
547d5ac3d36SDaniel Pereiraliberar ``buffer``. Evite usar nomes do GW-BASIC como ``err1:`` e ``err2:``,
548d5ac3d36SDaniel Pereiraporque você teria que renumerá-los se adicionasse ou removesse caminhos de
549d5ac3d36SDaniel Pereirasaída, e isso também torna a correção mais difícil de verificar.
550d5ac3d36SDaniel Pereira
551d5ac3d36SDaniel PereiraA justificativa para usar gotos é:
552d5ac3d36SDaniel Pereira
553d5ac3d36SDaniel Pereira- instruções incondicionais são mais fáceis de entender e seguir
554d5ac3d36SDaniel Pereira- o aninhamento é reduzido
555d5ac3d36SDaniel Pereira- erros por não atualizar pontos de saída individuais ao fazer
556d5ac3d36SDaniel Pereira  modificações são evitados
557d5ac3d36SDaniel Pereira- economiza o trabalho do compilador de otimizar e remover código redundante ;)
558d5ac3d36SDaniel Pereira
559d5ac3d36SDaniel Pereira.. code-block:: c
560d5ac3d36SDaniel Pereira
561d5ac3d36SDaniel Pereira	int fun(int a)
562d5ac3d36SDaniel Pereira	{
563d5ac3d36SDaniel Pereira		int result = 0;
564d5ac3d36SDaniel Pereira		char *buffer;
565d5ac3d36SDaniel Pereira
566d5ac3d36SDaniel Pereira		buffer = kmalloc(SIZE, GFP_KERNEL);
567d5ac3d36SDaniel Pereira		if (!buffer)
568d5ac3d36SDaniel Pereira			return -ENOMEM;
569d5ac3d36SDaniel Pereira
570d5ac3d36SDaniel Pereira		if (condition1) {
571d5ac3d36SDaniel Pereira			while (loop1) {
572d5ac3d36SDaniel Pereira				...
573d5ac3d36SDaniel Pereira			}
574d5ac3d36SDaniel Pereira			result = 1;
575d5ac3d36SDaniel Pereira			goto out_free_buffer;
576d5ac3d36SDaniel Pereira		}
577d5ac3d36SDaniel Pereira		...
578d5ac3d36SDaniel Pereira	out_free_buffer:
579d5ac3d36SDaniel Pereira		kfree(buffer);
580d5ac3d36SDaniel Pereira		return result;
581d5ac3d36SDaniel Pereira	}
582d5ac3d36SDaniel Pereira
583d5ac3d36SDaniel PereiraUm tipo comum de bug do qual você deve estar ciente é o ``one err bugs``
584d5ac3d36SDaniel Pereira(o "bug de um erro"), que se parece com isto:
585d5ac3d36SDaniel Pereira
586d5ac3d36SDaniel Pereira.. code-block:: c
587d5ac3d36SDaniel Pereira
588d5ac3d36SDaniel Pereira	err:
589d5ac3d36SDaniel Pereira		kfree(foo->bar);
590d5ac3d36SDaniel Pereira		kfree(foo);
591d5ac3d36SDaniel Pereira		return ret;
592d5ac3d36SDaniel Pereira
593d5ac3d36SDaniel PereiraO problema neste código é que, em alguns caminhos de saída, ``foo`` é NULL.
594d5ac3d36SDaniel PereiraNormalmente, a correção é dividir em dois rótulos de erro
595d5ac3d36SDaniel Pereira``err_free_bar:`` e ``err_free_foo:``:
596d5ac3d36SDaniel Pereira
597d5ac3d36SDaniel Pereira.. code-block:: c
598d5ac3d36SDaniel Pereira
599d5ac3d36SDaniel Pereira	err_free_bar:
600d5ac3d36SDaniel Pereira		kfree(foo->bar);
601d5ac3d36SDaniel Pereira	err_free_foo:
602d5ac3d36SDaniel Pereira		kfree(foo);
603d5ac3d36SDaniel Pereira		return ret;
604d5ac3d36SDaniel Pereira
605d5ac3d36SDaniel PereiraIdealmente, você deve simular erros para testar todos os caminhos de saída.
606d5ac3d36SDaniel Pereira
607d5ac3d36SDaniel Pereira
608d5ac3d36SDaniel Pereira8) Comentários
609d5ac3d36SDaniel Pereira--------------
610d5ac3d36SDaniel Pereira
611d5ac3d36SDaniel PereiraComentários são bons, mas também há o perigo de comentar demais. NUNCA tente
612d5ac3d36SDaniel Pereiraexplicar COMO o seu código funciona em um comentário: é muito melhor escrever
613d5ac3d36SDaniel Pereirao código de forma que o **funcionamento** seja óbvio, e é um desperdício de
614d5ac3d36SDaniel Pereiratempo explicar código mal escrito.
615d5ac3d36SDaniel Pereira
616d5ac3d36SDaniel PereiraEm geral, você quer que seus comentários digam O QUE o seu código faz, não
617d5ac3d36SDaniel PereiraCOMO. Também tente evitar colocar comentários dentro do corpo de uma função:
618d5ac3d36SDaniel Pereirase a função for tão complexa que você precisa comentar partes separadas dela,
619d5ac3d36SDaniel Pereiraprovavelmente você deveria voltar ao capítulo 6 por um tempo. Você pode fazer
620d5ac3d36SDaniel Pereirapequenos comentários para notar ou avisar sobre algo particularmente esperto
621d5ac3d36SDaniel Pereira(ou feio), mas tente evitar excesso. Em vez disso, coloque os comentários no
622d5ac3d36SDaniel Pereirainício da função, dizendo às pessoas o que ela faz e, possivelmente, POR QUE
623d5ac3d36SDaniel Pereiraela faz isso.
624d5ac3d36SDaniel Pereira
625d5ac3d36SDaniel PereiraAo comentar as funções da API do kernel, por favor use o formato kernel-doc.
626d5ac3d36SDaniel PereiraVeja os arquivos em :ref:`Documentation/doc-guide/ <doc_guide>` e
627d5ac3d36SDaniel Pereira``tools/docs/kernel-doc`` para detalhes. Observe que o perigo de comentar em
628d5ac3d36SDaniel Pereiraexcesso se aplica aos comentários kernel-doc da mesma forma. Não adicione
629d5ac3d36SDaniel Pereirakernel-doc genérico que apenas repete o que já é óbvio pela assinatura da
630d5ac3d36SDaniel Pereirafunção.
631d5ac3d36SDaniel Pereira
632d5ac3d36SDaniel PereiraO estilo preferido para comentários longos (em várias linhas) é:
633d5ac3d36SDaniel Pereira
634d5ac3d36SDaniel Pereira.. code-block:: c
635d5ac3d36SDaniel Pereira
636d5ac3d36SDaniel Pereira	/*
637d5ac3d36SDaniel Pereira	 * Este é o estilo preferido para comentários em várias linhas
638d5ac3d36SDaniel Pereira	 * no código-fonte do kernel Linux.
639d5ac3d36SDaniel Pereira	 * Por favor, use-o de forma consistente.
640d5ac3d36SDaniel Pereira	 *
641d5ac3d36SDaniel Pereira	 * Descrição: uma coluna de asteriscos à esquerda,
642d5ac3d36SDaniel Pereira	 * com linhas de início e fim quase vazias.
643d5ac3d36SDaniel Pereira	 */
644d5ac3d36SDaniel Pereira
645d5ac3d36SDaniel PereiraTambém é importante comentar dados, sejam tipos básicos ou tipos derivados.
646d5ac3d36SDaniel PereiraPara isso, use apenas uma declaração de dado por linha (sem vírgulas para
647d5ac3d36SDaniel Pereiramúltiplas declarações de dados). Isso deixa espaço para um pequeno comentário
648d5ac3d36SDaniel Pereiraem cada item explicando seu uso.
649d5ac3d36SDaniel Pereira
650d5ac3d36SDaniel Pereira
651d5ac3d36SDaniel Pereira9) Você fez uma bagunça
652d5ac3d36SDaniel Pereira-----------------------
653d5ac3d36SDaniel Pereira
654d5ac3d36SDaniel PereiraTudo bem, todos fazemos isso. Você provavelmente foi informado por seu
655d5ac3d36SDaniel Pereiraauxiliar de longa data em Unix que o ``GNU emacs`` formata automaticamente os
656d5ac3d36SDaniel Pereiraarquivos-fonte em C para você, e você percebeu que ele realmente faz isso, mas as
657d5ac3d36SDaniel Pereiraconfigurações padrão que ele usa são menos do que desejáveis (na verdade,
658d5ac3d36SDaniel Pereiraelas são piores do que digitação aleatória - um número infinito de macacos
659d5ac3d36SDaniel Pereiradigitando no GNU emacs nunca faria um bom programa).
660d5ac3d36SDaniel Pereira
661d5ac3d36SDaniel PereiraEntão, você pode ou se livrar do GNU emacs, ou mudar para usar valores mais
662d5ac3d36SDaniel Pereirasãos. Para fazer isso, você pode colocar o seguinte no seu arquivo .emacs:
663d5ac3d36SDaniel Pereira
664d5ac3d36SDaniel Pereira.. code-block:: elisp
665d5ac3d36SDaniel Pereira
666d5ac3d36SDaniel Pereira  (defun c-lineup-arglist-tabs-only (ignored)
667d5ac3d36SDaniel Pereira    "Line up argument lists by tabs, not spaces"
668d5ac3d36SDaniel Pereira    (let* ((anchor (c-langelem-pos c-syntactic-element))
669d5ac3d36SDaniel Pereira          (column (c-langelem-2nd-pos c-syntactic-element))
670d5ac3d36SDaniel Pereira          (offset (- (1+ column) anchor))
671d5ac3d36SDaniel Pereira          (steps (floor offset c-basic-offset)))
672d5ac3d36SDaniel Pereira      (* (max steps 1)
673d5ac3d36SDaniel Pereira         c-basic-offset)))
674d5ac3d36SDaniel Pereira
675d5ac3d36SDaniel Pereira  (dir-locals-set-class-variables
676d5ac3d36SDaniel Pereira   'linux-kernel
677d5ac3d36SDaniel Pereira   '((c-mode . (
678d5ac3d36SDaniel Pereira          (c-basic-offset . 8)
679d5ac3d36SDaniel Pereira          (c-label-minimum-indentation . 0)
680d5ac3d36SDaniel Pereira          (c-offsets-alist . (
681d5ac3d36SDaniel Pereira                  (arglist-close         . c-lineup-arglist-tabs-only)
682d5ac3d36SDaniel Pereira                  (arglist-cont-nonempty .
683d5ac3d36SDaniel Pereira                      (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
684d5ac3d36SDaniel Pereira                  (arglist-intro         . +)
685d5ac3d36SDaniel Pereira                  (brace-list-intro      . +)
686d5ac3d36SDaniel Pereira                  (c                     . c-lineup-C-comments)
687d5ac3d36SDaniel Pereira                  (case-label            . 0)
688d5ac3d36SDaniel Pereira                  (comment-intro         . c-lineup-comment)
689d5ac3d36SDaniel Pereira                  (cpp-define-intro      . +)
690d5ac3d36SDaniel Pereira                  (cpp-macro             . -1000)
691d5ac3d36SDaniel Pereira                  (cpp-macro-cont        . +)
692d5ac3d36SDaniel Pereira                  (defun-block-intro     . +)
693d5ac3d36SDaniel Pereira                  (else-clause           . 0)
694d5ac3d36SDaniel Pereira                  (func-decl-cont        . +)
695d5ac3d36SDaniel Pereira                  (inclass               . +)
696d5ac3d36SDaniel Pereira                  (inher-cont            . c-lineup-multi-inher)
697d5ac3d36SDaniel Pereira                  (knr-argdecl-intro     . 0)
698d5ac3d36SDaniel Pereira                  (label                 . -1000)
699d5ac3d36SDaniel Pereira                  (statement             . 0)
700d5ac3d36SDaniel Pereira                  (statement-block-intro . +)
701d5ac3d36SDaniel Pereira                  (statement-case-intro  . +)
702d5ac3d36SDaniel Pereira                  (statement-cont        . +)
703d5ac3d36SDaniel Pereira                  (substatement          . +)
704d5ac3d36SDaniel Pereira                  ))
705d5ac3d36SDaniel Pereira          (indent-tabs-mode . t)
706d5ac3d36SDaniel Pereira          (show-trailing-whitespace . t)
707d5ac3d36SDaniel Pereira          ))))
708d5ac3d36SDaniel Pereira
709d5ac3d36SDaniel Pereira  (dir-locals-set-directory-class
710d5ac3d36SDaniel Pereira   (expand-file-name "~/src/linux-trees")
711d5ac3d36SDaniel Pereira   'linux-kernel)
712d5ac3d36SDaniel Pereira
713d5ac3d36SDaniel PereiraIsso fará o emacs funcionar melhor com o estilo de codificação do kernel para
714d5ac3d36SDaniel Pereiraarquivos C abaixo de ``~/src/linux-trees``.
715d5ac3d36SDaniel Pereira
716d5ac3d36SDaniel PereiraMas, mesmo que você falhe em fazer o emacs formatar de maneira sensata, nem
717d5ac3d36SDaniel Pereiratudo está perdido: use ``indent``.
718d5ac3d36SDaniel Pereira
719d5ac3d36SDaniel PereiraAgora, novamente, o GNU indent tem as mesmas configurações sem cérebro do GNU
720d5ac3d36SDaniel Pereiraemacs, e é por isso que você precisa dar a ele algumas opções de linha de
721d5ac3d36SDaniel Pereiracomando. No entanto, isso não é tão ruim, porque até os criadores do GNU
722d5ac3d36SDaniel Pereiraindent reconhecem a autoridade do K&R (as pessoas do GNU não são más, apenas
723d5ac3d36SDaniel Pereiraestão gravemente equivocadas nessa questão), então você apenas dá ao indent as
724d5ac3d36SDaniel Pereiraopções ``-kr -i8`` (que significa ``K&R, indentações de 8 caracteres``), ou
725d5ac3d36SDaniel Pereirausa ``scripts/Lindent``, que indenta no estilo mais recente.
726d5ac3d36SDaniel Pereira
727d5ac3d36SDaniel Pereira``indent`` tem muitas opções, e especialmente quando se trata de reformatação
728d5ac3d36SDaniel Pereirade comentários, você pode querer dar uma olhada na página de manual. Mas
729d5ac3d36SDaniel Pereiralembre-se: ``indent`` não é uma solução para programação ruim.
730d5ac3d36SDaniel Pereira
731d5ac3d36SDaniel PereiraObserve que você também pode usar a ferramenta ``clang-format`` para ajudá-lo
732d5ac3d36SDaniel Pereiracom essas regras, para reformatar rapidamente partes do seu código
733d5ac3d36SDaniel Pereiraautomaticamente e revisar arquivos completos para detectar erros de estilo de
734d5ac3d36SDaniel Pereiracodificação, erros de digitação e possíveis melhorias. Também é útil para
735d5ac3d36SDaniel Pereiraordenar ``#includes``, alinhar variáveis/macros, reorganizar texto e outras
736d5ac3d36SDaniel Pereiratarefas semelhantes. Consulte o arquivo
737d5ac3d36SDaniel Pereira:ref:`Documentation/dev-tools/clang-format.rst <clangformat>`
738d5ac3d36SDaniel Pereirapara obter mais detalhes.
739d5ac3d36SDaniel Pereira
740d5ac3d36SDaniel PereiraAlgumas configurações básicas do editor, como indentação e finais de linha,
741d5ac3d36SDaniel Pereiraserão definidas automaticamente se você estiver usando um editor compatível com
742d5ac3d36SDaniel Pereirao EditorConfig. Consulte o site oficial do EditorConfig para obter mais
743d5ac3d36SDaniel Pereirainformação: https://editorconfig.org/
744d5ac3d36SDaniel Pereira
745d5ac3d36SDaniel Pereira10) Arquivos de configuração Kconfig
746d5ac3d36SDaniel Pereira------------------------------------
747d5ac3d36SDaniel Pereira
748d5ac3d36SDaniel PereiraPara todos os arquivos de configuração Kconfig* em toda a árvore de origem,
749d5ac3d36SDaniel Pereiraa indentação é um pouco diferente. Linhas sob uma definição ``config`` são
750d5ac3d36SDaniel Pereiraindentadas com uma tabulação, enquanto o texto de ajuda é indentado com mais
751d5ac3d36SDaniel Pereiradois espaços. Exemplo::
752d5ac3d36SDaniel Pereira
753d5ac3d36SDaniel Pereira  config AUDIT
754d5ac3d36SDaniel Pereira	bool "Auditing support"
755d5ac3d36SDaniel Pereira	depends on NET
756d5ac3d36SDaniel Pereira	help
757d5ac3d36SDaniel Pereira	  Enable auditing infrastructure that can be used with another
758d5ac3d36SDaniel Pereira	  kernel subsystem, such as SELinux (which requires this for
759d5ac3d36SDaniel Pereira	  logging of avc messages output).  Does not do system-call
760d5ac3d36SDaniel Pereira	  auditing without CONFIG_AUDITSYSCALL.
761d5ac3d36SDaniel Pereira
762d5ac3d36SDaniel PereiraRecursos seriamente perigosos (como suporte de gravação para certos sistemas
763d5ac3d36SDaniel Pereirade arquivos) devem anunciar isso de forma proeminente na string do prompt::
764d5ac3d36SDaniel Pereira
765d5ac3d36SDaniel Pereira  config ADFS_FS_RW
766d5ac3d36SDaniel Pereira	bool "ADFS write support (DANGEROUS)"
767d5ac3d36SDaniel Pereira	depends on ADFS_FS
768d5ac3d36SDaniel Pereira	...
769d5ac3d36SDaniel Pereira
770d5ac3d36SDaniel PereiraPara documentação completa sobre os arquivos de configuração, consulte o
771d5ac3d36SDaniel Pereiraarquivo Documentation/kbuild/kconfig-language.rst.
772d5ac3d36SDaniel Pereira
773d5ac3d36SDaniel Pereira
774d5ac3d36SDaniel Pereira11) Estruturas de dados
775d5ac3d36SDaniel Pereira-----------------------
776d5ac3d36SDaniel Pereira
777d5ac3d36SDaniel PereiraEstruturas de dados que tenham visibilidade fora do ambiente monothread em que
778d5ac3d36SDaniel Pereirasão criadas e destruídas devem ter contadores de referência. No kernel, coleta
779d5ac3d36SDaniel Pereirade lixo não existe (e fora do kernel, a coleta de lixo é lenta e
780d5ac3d36SDaniel Pereiraineficiente), o que significa que você absolutamente **precisa** contar todas
781d5ac3d36SDaniel Pereiraas referências de uso.
782d5ac3d36SDaniel Pereira
783d5ac3d36SDaniel PereiraContagem de referência significa que você pode evitar bloqueios e permite que
784d5ac3d36SDaniel Pereiramúltiplos usuários tenham acesso à estrutura de dados em paralelo - sem se
785d5ac3d36SDaniel Pereirapreocupar com a estrutura desaparecendo debaixo deles do nada apenas porque
786d5ac3d36SDaniel Pereiraeles dormiram ou fizeram outra coisa por um tempo.
787d5ac3d36SDaniel Pereira
788d5ac3d36SDaniel PereiraObserve que bloqueio **não** substitui contagem de referência. O bloqueio é
789d5ac3d36SDaniel Pereirausado para manter estruturas de dados coerentes, enquanto a contagem de
790d5ac3d36SDaniel Pereirareferência é uma técnica de gerenciamento de memória. Normalmente, ambos são
791d5ac3d36SDaniel Pereiranecessários, e não devem ser confundidos entre si.
792d5ac3d36SDaniel Pereira
793d5ac3d36SDaniel PereiraMuitas estruturas de dados podem, de fato, ter dois níveis de contagem de
794d5ac3d36SDaniel Pereirareferência, quando existem usuários de diferentes ``classes``. A contagem da
795d5ac3d36SDaniel Pereirasubclasse conta o número de usuários da subclasse e decrementa a contagem
796d5ac3d36SDaniel Pereiraglobal apenas uma vez quando a contagem da subclasse chega a zero.
797d5ac3d36SDaniel Pereira
798d5ac3d36SDaniel PereiraExemplos desse tipo de ``multi-level-reference-counting`` podem ser encontrados
799d5ac3d36SDaniel Pereiraem gerenciamento de memória (``struct mm_struct``: mm_users e mm_count) e em
800d5ac3d36SDaniel Pereiracódigo de sistema de arquivos (``struct super_block``: s_count e s_active).
801d5ac3d36SDaniel Pereira
802d5ac3d36SDaniel PereiraLembre-se: se outra thread puder encontrar sua estrutura de dados, e você não
803d5ac3d36SDaniel Pereirativer contagem de referência nela, quase certamente há um bug.
804d5ac3d36SDaniel Pereira
805d5ac3d36SDaniel Pereira
806d5ac3d36SDaniel Pereira12) Macros, enums e RTL
807d5ac3d36SDaniel Pereira-----------------------
808d5ac3d36SDaniel Pereira
809d5ac3d36SDaniel PereiraNomes de macros que definem constantes e rótulos em enums são maiúsculos.
810d5ac3d36SDaniel Pereira
811d5ac3d36SDaniel Pereira.. code-block:: c
812d5ac3d36SDaniel Pereira
813d5ac3d36SDaniel Pereira	#define CONSTANT 0x12345
814d5ac3d36SDaniel Pereira
815d5ac3d36SDaniel PereiraEnums são preferidos quando várias constantes relacionadas são definidas.
816d5ac3d36SDaniel Pereira
817d5ac3d36SDaniel PereiraNomes de macro em maiúsculas são apreciados, mas macros que se parecem com
818d5ac3d36SDaniel Pereirafunções podem ser nomeadas em minúsculas.
819d5ac3d36SDaniel Pereira
820d5ac3d36SDaniel PereiraEm geral, funções inline são preferíveis a macros que se parecem com funções.
821d5ac3d36SDaniel Pereira
822d5ac3d36SDaniel PereiraMacros com múltiplas instruções devem ser envoltas em um bloco do-while:
823d5ac3d36SDaniel Pereira
824d5ac3d36SDaniel Pereira.. code-block:: c
825d5ac3d36SDaniel Pereira
826d5ac3d36SDaniel Pereira	#define macrofun(a, b, c) \
827d5ac3d36SDaniel Pereira		do { \
828d5ac3d36SDaniel Pereira			if (a == 5) \
829d5ac3d36SDaniel Pereira				do_this(b, c); \
830d5ac3d36SDaniel Pereira		} while (0)
831d5ac3d36SDaniel Pereira
832d5ac3d36SDaniel PereiraMacros do tipo função com parâmetros não usados devem ser substituídas por
833d5ac3d36SDaniel Pereirafunções estáticas inline para evitar o problema de variáveis não usadas:
834d5ac3d36SDaniel Pereira
835d5ac3d36SDaniel Pereira.. code-block:: c
836d5ac3d36SDaniel Pereira
837d5ac3d36SDaniel Pereira	static inline void fun(struct foo *foo)
838d5ac3d36SDaniel Pereira	{
839d5ac3d36SDaniel Pereira	}
840d5ac3d36SDaniel Pereira
841d5ac3d36SDaniel PereiraDevido a práticas históricas, muitos arquivos ainda empregam a abordagem
842d5ac3d36SDaniel Pereira"cast para (void)" para avaliar parâmetros. No entanto, esse método não é
843d5ac3d36SDaniel Pereiraaconselhável.
844d5ac3d36SDaniel PereiraFunções inline resolvem o problema de "expressão com efeitos colaterais
845d5ac3d36SDaniel Pereiraavaliada mais de uma vez", contornam problemas de variáveis não usadas e, por
846d5ac3d36SDaniel Pereiraalgum motivo, geralmente são mais bem documentadas do que macros.
847d5ac3d36SDaniel Pereira
848d5ac3d36SDaniel Pereira.. code-block:: c
849d5ac3d36SDaniel Pereira
850d5ac3d36SDaniel Pereira	/*
851d5ac3d36SDaniel Pereira	 * Evite fazer isto sempre que possível e prefira funções estáticas
852d5ac3d36SDaniel Pereira	 * inline
853d5ac3d36SDaniel Pereira	 */
854d5ac3d36SDaniel Pereira	#define macrofun(foo) do { (void) (foo); } while (0)
855d5ac3d36SDaniel Pereira
856d5ac3d36SDaniel PereiraCoisas a evitar ao usar macros:
857d5ac3d36SDaniel Pereira
858d5ac3d36SDaniel Pereira1) macros que afetam o fluxo de controle:
859d5ac3d36SDaniel Pereira
860d5ac3d36SDaniel Pereira.. code-block:: c
861d5ac3d36SDaniel Pereira
862d5ac3d36SDaniel Pereira	#define FOO(x) \
863d5ac3d36SDaniel Pereira		do { \
864d5ac3d36SDaniel Pereira			if (blah(x) < 0) \
865d5ac3d36SDaniel Pereira				return -EBUGGERED; \
866d5ac3d36SDaniel Pereira		} while (0)
867d5ac3d36SDaniel Pereira
868d5ac3d36SDaniel Pereiraé uma ideia **muito** ruim. Ela parece uma chamada de função, mas sai da
869d5ac3d36SDaniel Pereirafunção ``calling``; não quebre os parsers internos de quem lerá o código.
870d5ac3d36SDaniel Pereira
871d5ac3d36SDaniel Pereira2) macros que dependem de ter uma variável local com um nome mágico:
872d5ac3d36SDaniel Pereira
873d5ac3d36SDaniel Pereira.. code-block:: c
874d5ac3d36SDaniel Pereira
875d5ac3d36SDaniel Pereira	#define FOO(val) bar(index, val)
876d5ac3d36SDaniel Pereira
877d5ac3d36SDaniel Pereirapode parecer uma boa coisa, mas é confuso pra caramba para quem lê o código e
878d5ac3d36SDaniel Pereiraé propenso a quebrar com mudanças aparentemente inocentes.
879d5ac3d36SDaniel Pereira
880d5ac3d36SDaniel Pereira3) macros com argumentos usados como l-values: FOO(x) = y; vai te morder se
881d5ac3d36SDaniel Pereiraalguém, por exemplo, transformar FOO em uma função inline.
882d5ac3d36SDaniel Pereira
883d5ac3d36SDaniel Pereira4) esquecer da precedência: macros que definem constantes usando expressões
884d5ac3d36SDaniel Pereiradevem colocar a expressão entre parênteses. Cuidado com problemas semelhantes
885d5ac3d36SDaniel Pereiracom macros que usam parâmetros.
886d5ac3d36SDaniel Pereira
887d5ac3d36SDaniel Pereira.. code-block:: c
888d5ac3d36SDaniel Pereira
889d5ac3d36SDaniel Pereira	#define CONSTANT 0x4000
890d5ac3d36SDaniel Pereira	#define CONSTEXP (CONSTANT | 3)
891d5ac3d36SDaniel Pereira
892d5ac3d36SDaniel Pereira5) colisões de namespace ao definir variáveis locais em macros que se
893d5ac3d36SDaniel Pereiraparecem com funções:
894d5ac3d36SDaniel Pereira
895d5ac3d36SDaniel Pereira.. code-block:: c
896d5ac3d36SDaniel Pereira
897d5ac3d36SDaniel Pereira	#define FOO(x)				\
898d5ac3d36SDaniel Pereira	({					\
899d5ac3d36SDaniel Pereira		typeof(x) ret;			\
900d5ac3d36SDaniel Pereira		ret = calc_ret(x);		\
901d5ac3d36SDaniel Pereira		(ret);				\
902d5ac3d36SDaniel Pereira	})
903d5ac3d36SDaniel Pereira
904d5ac3d36SDaniel Pereira``ret`` é um nome comum para uma variável local - ``__foo_ret`` tem menos
905d5ac3d36SDaniel Pereirachance de colidir com uma variável existente.
906d5ac3d36SDaniel Pereira
907d5ac3d36SDaniel PereiraO manual do cpp trata de macros de forma exaustiva. O manual interno do gcc
908d5ac3d36SDaniel Pereiratambém cobre o RTL, que é usado frequentemente com linguagem de montagem no
909d5ac3d36SDaniel Pereirakernel.
910d5ac3d36SDaniel Pereira
911d5ac3d36SDaniel Pereira
912d5ac3d36SDaniel Pereira13) Imprimindo mensagens do kernel
913d5ac3d36SDaniel Pereira----------------------------------
914d5ac3d36SDaniel Pereira
915d5ac3d36SDaniel PereiraDesenvolvedores do kernel gostam de ser vistos como letrados. Preste atenção à
916d5ac3d36SDaniel Pereiraortografia das mensagens do kernel para causar uma boa impressão. Não use
917d5ac3d36SDaniel Pereiracontrações incorretas como ``dont``; use ``do not`` ou ``don't`` em vez
918d5ac3d36SDaniel Pereiradisso. Faça as mensagens concisas, claras e inequívocas.
919d5ac3d36SDaniel Pereira
920d5ac3d36SDaniel PereiraMensagens do kernel não precisam terminar com ponto.
921d5ac3d36SDaniel Pereira
922d5ac3d36SDaniel PereiraImprimir números entre parênteses (%d) não agrega valor e deve ser evitado.
923d5ac3d36SDaniel Pereira
924d5ac3d36SDaniel PereiraHá vários macros de diagnóstico do modelo de driver em <linux/dev_printk.h>
925d5ac3d36SDaniel Pereiraque você deve usar para garantir que as mensagens sejam correspondidas ao
926d5ac3d36SDaniel Pereiradispositivo e driver corretos e sejam marcadas com o nível certo: ``dev_err()``,
927d5ac3d36SDaniel Pereira``dev_warn()``, ``dev_info()`` e assim por diante. Para mensagens que não
928d5ac3d36SDaniel Pereiraestão associadas a um device específico, <linux/printk.h> define
929d5ac3d36SDaniel Pereira``pr_notice()``, ``pr_info()``, ``pr_warn()``, ``pr_err()`` etc. Quando os
930d5ac3d36SDaniel Pereiradrivers funcionam corretamente, eles ficam silenciosos, então prefira usar
931d5ac3d36SDaniel Pereira``dev_dbg``/``pr_debug`` a menos que algo esteja errado.
932d5ac3d36SDaniel Pereira
933d5ac3d36SDaniel PereiraEncontrar boas mensagens de depuração pode ser um desafio; e, uma vez que
934d5ac3d36SDaniel Pereiravocê tenha essas mensagens, elas podem ajudar bastante para solução de
935d5ac3d36SDaniel Pereiraproblemas remota. No entanto, a impressão de mensagens de depuração é tratada
936d5ac3d36SDaniel Pereiradiferentemente da impressão de outras mensagens não de depuração. Enquanto as
937d5ac3d36SDaniel Pereiraoutras funções ``pr_XXX()`` imprimem incondicionalmente, ``pr_debug()`` não;
938d5ac3d36SDaniel Pereiraela é compilada fora por padrão, a menos que ``DEBUG`` seja definido ou
939d5ac3d36SDaniel Pereira``CONFIG_DYNAMIC_DEBUG`` esteja configurado. Isso também vale para
940d5ac3d36SDaniel Pereira``dev_dbg()``, e uma convenção relacionada usa ``VERBOSE_DEBUG`` para adicionar
941d5ac3d36SDaniel Pereiramensagens ``dev_vdbg()`` às já habilitadas por ``DEBUG``.
942d5ac3d36SDaniel Pereira
943d5ac3d36SDaniel PereiraMuitos subsistemas têm opções de depuração do Kconfig para ativar ``-DDEBUG``
944d5ac3d36SDaniel Pereirano Makefile correspondente; em outros casos, arquivos específicos fazem
945d5ac3d36SDaniel Pereira``#define DEBUG``. E quando uma mensagem de depuração deve ser impressa
946d5ac3d36SDaniel Pereiraincondicionalmente, por exemplo, se ela já estiver dentro de uma seção
947d5ac3d36SDaniel Pereira``#ifdef`` relacionada à depuração, pode-se usar ``printk(KERN_DEBUG ...)``.
948d5ac3d36SDaniel Pereira
949d5ac3d36SDaniel Pereira
950d5ac3d36SDaniel Pereira14) Alocando memória
951d5ac3d36SDaniel Pereira--------------------
952d5ac3d36SDaniel Pereira
953d5ac3d36SDaniel PereiraO kernel fornece os seguintes alocadores de memória de uso geral:
954d5ac3d36SDaniel Pereira``kmalloc()``, ``kzalloc()``, ``kmalloc_objs()``, ``kzalloc_objs()``,
955d5ac3d36SDaniel Pereira``vmalloc()`` e ``vzalloc()``. Consulte a documentação da API para obter mais
956d5ac3d36SDaniel Pereirainformações sobre eles. :ref:`Documentation/core-api/memory-allocation.rst
957d5ac3d36SDaniel Pereira<memory_allocation>`
958d5ac3d36SDaniel Pereira
959d5ac3d36SDaniel PereiraA forma preferida de passar o tamanho de uma estrutura é a seguinte:
960d5ac3d36SDaniel Pereira
961d5ac3d36SDaniel Pereira.. code-block:: c
962d5ac3d36SDaniel Pereira
963d5ac3d36SDaniel Pereira	p = kmalloc_obj(*p, ...);
964d5ac3d36SDaniel Pereira
965d5ac3d36SDaniel PereiraA forma alternativa em que o nome da estrutura é escrito explicitamente piora a
966d5ac3d36SDaniel Pereiralegibilidade e cria oportunidade para um bug quando o tipo da variável ponteiro
967d5ac3d36SDaniel Pereiraé alterado, mas o ``sizeof`` correspondente passado para um alocador de memória
968d5ac3d36SDaniel Pereiranão é.
969d5ac3d36SDaniel Pereira
970d5ac3d36SDaniel PereiraCasting do valor de retorno, que é um ponteiro ``void``, é redundante. A
971d5ac3d36SDaniel Pereiraconversão de ponteiro ``void`` para qualquer outro tipo de ponteiro é garantida
972d5ac3d36SDaniel Pereirapela linguagem de programação C.
973d5ac3d36SDaniel Pereira
974d5ac3d36SDaniel PereiraA forma preferida para alocar um array é a seguinte:
975d5ac3d36SDaniel Pereira
976d5ac3d36SDaniel Pereira.. code-block:: c
977d5ac3d36SDaniel Pereira
978d5ac3d36SDaniel Pereira	p = kmalloc_objs(*p, n, ...);
979d5ac3d36SDaniel Pereira
980d5ac3d36SDaniel PereiraA forma preferida para alocar um array zerado é a seguinte:
981d5ac3d36SDaniel Pereira
982d5ac3d36SDaniel Pereira.. code-block:: c
983d5ac3d36SDaniel Pereira
984d5ac3d36SDaniel Pereira	p = kzalloc_objs(*p, n, ...);
985d5ac3d36SDaniel Pereira
986d5ac3d36SDaniel PereiraAs duas formas verificam estouro no tamanho de alocação ``n * sizeof(...)`` e
987d5ac3d36SDaniel Pereiraretornam ``NULL`` se isso ocorrer.
988d5ac3d36SDaniel Pereira
989d5ac3d36SDaniel PereiraEssas funções genéricas de alocação emitem um dump de pilha em caso de falha
990d5ac3d36SDaniel Pereiraquando usadas sem ``__GFP_NOWARN``, então não há utilidade em emitir uma
991d5ac3d36SDaniel Pereiramensagem de falha adicional quando ``NULL`` é retornado.
992d5ac3d36SDaniel Pereira
993d5ac3d36SDaniel Pereira15) A doença do inline
994d5ac3d36SDaniel Pereira----------------------
995d5ac3d36SDaniel Pereira
996d5ac3d36SDaniel PereiraParece haver uma percepção errônea comum de que o gcc tem uma opção mágica de
997d5ac3d36SDaniel Pereiraaceleração chamada ``inline``. Embora o uso de ``inline`` possa ser apropriado
998d5ac3d36SDaniel Pereira(por exemplo, como uma forma de substituir macros; veja o Capítulo 12), muitas
999d5ac3d36SDaniel Pereiravezes não é. O uso abundante da palavra-chave ``inline`` leva a um kernel
1000d5ac3d36SDaniel Pereiramuito maior, o que, por sua vez, torna o sistema mais lento como um todo, por
1001d5ac3d36SDaniel Pereiracausa de uma maior ocupação de i-cache para a CPU e simplesmente porque há menos
1002d5ac3d36SDaniel Pereiramemória disponível para o ``pagecache``. Pense nisso: uma falha no pagecache
1003d5ac3d36SDaniel Pereiracausa um seek no disco, que facilmente leva 5 milissegundos. Há MUITOS ciclos
1004d5ac3d36SDaniel Pereirade CPU que podem entrar nesses 5 milissegundos.
1005d5ac3d36SDaniel Pereira
1006d5ac3d36SDaniel PereiraUma regra prática razoável é não colocar ``inline`` em funções com mais de 3
1007d5ac3d36SDaniel Pereiralinhas de código. Uma exceção a essa regra são os casos em que um parâmetro é
1008d5ac3d36SDaniel Pereiraconhecido como uma constante em tempo de compilação, e como resultado dessa
1009d5ac3d36SDaniel Pereiraconstância você *sabe* que o compilador será capaz de otimizar grande parte da
1010d5ac3d36SDaniel Pereirasua função em tempo de compilação. Para um bom exemplo desse caso posterior,
1011d5ac3d36SDaniel Pereiraveja a função inline ``kmalloc()``.
1012d5ac3d36SDaniel Pereira
1013d5ac3d36SDaniel PereiraMuitas pessoas argumentam que adicionar ``inline`` a funções ``static`` usadas
1014d5ac3d36SDaniel Pereiraapenas uma vez é sempre uma vantagem, porque não há custo de espaço. Embora
1015d5ac3d36SDaniel Pereiraisso seja tecnicamente correto, o gcc é capaz de fazer esse inline
1016d5ac3d36SDaniel Pereiraautomaticamente sem ajuda, e a questão de manutenção de remover o ``inline``
1017d5ac3d36SDaniel Pereiraquando um segundo usuário aparece supera o valor potencial da dica que diz ao
1018d5ac3d36SDaniel Pereiragcc para fazer algo que ele faria de qualquer forma.
1019d5ac3d36SDaniel Pereira
1020d5ac3d36SDaniel Pereira
1021d5ac3d36SDaniel Pereira16) Valores e nomes de retorno de função
1022d5ac3d36SDaniel Pereira----------------------------------------
1023d5ac3d36SDaniel Pereira
1024d5ac3d36SDaniel PereiraFunções podem retornar valores de vários tipos, e um dos mais comuns é um valor
1025d5ac3d36SDaniel Pereiraque indica se a função teve sucesso ou falhou. Esse valor pode ser representado
1026d5ac3d36SDaniel Pereiracomo um inteiro de código de erro (-Exxx = falha, 0 = sucesso) ou como um
1027d5ac3d36SDaniel Pereirabooleano ``succeeded`` (0 = falha, diferente de zero = sucesso).
1028d5ac3d36SDaniel Pereira
1029d5ac3d36SDaniel PereiraMisturar esses dois tipos de representação é uma fonte fértil de bugs difíceis
1030d5ac3d36SDaniel Pereirade encontrar. Se a linguagem C incluísse uma distinção forte entre inteiros e
1031d5ac3d36SDaniel Pereirabooleanos, o compilador encontraria esses erros para nós... mas não inclui. Para
1032d5ac3d36SDaniel Pereiraajudar a evitar esses bugs, siga sempre esta convenção::
1033d5ac3d36SDaniel Pereira
1034d5ac3d36SDaniel Pereira	Se o nome de uma função for uma ação ou um comando imperativo,
1035d5ac3d36SDaniel Pereira	a função deve retornar um inteiro de código de erro. Se o nome
1036d5ac3d36SDaniel Pereira	for um predicado, a função deve retornar um booleano de "sucesso".
1037d5ac3d36SDaniel Pereira
1038d5ac3d36SDaniel PereiraPor exemplo, ``add work`` é um comando, e a função ``add_work()`` retorna 0
1039d5ac3d36SDaniel Pereirapara sucesso ou -EBUSY para falha. Da mesma forma, ``PCI device present`` é um
1040d5ac3d36SDaniel Pereirapredicado, e a função ``pci_dev_present()`` retorna 1 se encontrar um device
1041d5ac3d36SDaniel Pereiracorrespondente ou 0 se não encontrar.
1042d5ac3d36SDaniel Pereira
1043d5ac3d36SDaniel PereiraTodas as funções ``EXPORT`` devem respeitar esta convenção, e assim também
1044d5ac3d36SDaniel Pereiradevem todas as funções públicas. Funções privadas (``static``) não precisam,
1045d5ac3d36SDaniel Pereiramas é recomendável que o façam.
1046d5ac3d36SDaniel Pereira
1047d5ac3d36SDaniel PereiraFunções cujo valor de retorno é o resultado real de um cálculo, em vez de uma
1048d5ac3d36SDaniel Pereiraindicação de se o cálculo teve sucesso, não estão sujeitas a essa regra.
1049d5ac3d36SDaniel PereiraNormalmente, elas indicam falha retornando algum resultado fora do intervalo.
1050d5ac3d36SDaniel PereiraExemplos típicos seriam funções que retornam ponteiros; elas usam ``NULL`` ou o
1051d5ac3d36SDaniel Pereiramecanismo ``ERR_PTR`` para informar falha.
1052d5ac3d36SDaniel Pereira
1053d5ac3d36SDaniel Pereira
1054d5ac3d36SDaniel Pereira17) Usando bool
1055d5ac3d36SDaniel Pereira---------------
1056d5ac3d36SDaniel Pereira
1057d5ac3d36SDaniel PereiraO tipo ``bool`` do kernel Linux é um alias do tipo C99 ``_Bool``. Valores
1058d5ac3d36SDaniel Pereira``bool`` só podem avaliar para 0 ou 1, e conversão implícita ou explícita para
1059d5ac3d36SDaniel Pereira``bool`` converte automaticamente o valor para verdadeiro ou falso. Ao usar
1060d5ac3d36SDaniel Pereiratipos ``bool``, a construção ``!!`` não é necessária, o que elimina uma classe
1061d5ac3d36SDaniel Pereirade bugs.
1062d5ac3d36SDaniel Pereira
1063d5ac3d36SDaniel PereiraAo trabalhar com valores ``bool``, as definições ``true`` e ``false`` devem ser
1064d5ac3d36SDaniel Pereirausadas em vez de 1 e 0.
1065d5ac3d36SDaniel Pereira
1066d5ac3d36SDaniel PereiraTipos de retorno de função ``bool`` e variáveis locais na pilha são sempre
1067d5ac3d36SDaniel Pereiraválidos quando apropriados. O uso de ``bool`` é encorajado para melhorar a
1068d5ac3d36SDaniel Pereiralegibilidade e muitas vezes é uma opção melhor do que ``int`` para armazenar
1069d5ac3d36SDaniel Pereiravalores booleanos.
1070d5ac3d36SDaniel Pereira
1071d5ac3d36SDaniel PereiraNão use ``bool`` se o layout da linha de cache ou o tamanho do valor importar,
1072d5ac3d36SDaniel Pereiraporque seu tamanho e alinhamento variam conforme a arquitetura compilada.
1073d5ac3d36SDaniel PereiraEstruturas otimizadas para alinhamento e tamanho não devem usar ``bool``.
1074d5ac3d36SDaniel Pereira
1075d5ac3d36SDaniel PereiraSe uma estrutura tiver muitos valores verdadeiro/falso, considere consolidá-los
1076d5ac3d36SDaniel Pereiraem um ``bitfield`` com membros de 1 bit, ou usar um tipo de largura fixa
1077d5ac3d36SDaniel Pereiraapropriado, como ``u8``.
1078d5ac3d36SDaniel Pereira
1079d5ac3d36SDaniel PereiraDa mesma forma, para argumentos de função, muitos valores verdadeiro/falso podem
1080d5ac3d36SDaniel Pereiraser consolidados em um único argumento de sinalizadores bit a bit, e
1081d5ac3d36SDaniel Pereira``flags`` muitas vezes pode ser uma alternativa mais legível se os pontos de
1082d5ac3d36SDaniel Pereirachamada tiverem constantes verdadeiras/falsas "nuas".
1083d5ac3d36SDaniel Pereira
1084d5ac3d36SDaniel PereiraCaso contrário, o uso limitado de ``bool`` em estruturas e argumentos pode
1085d5ac3d36SDaniel Pereiramelhorar a legibilidade.
1086d5ac3d36SDaniel Pereira
1087d5ac3d36SDaniel Pereira18) Não reinventando as macros do kernel
1088d5ac3d36SDaniel Pereira----------------------------------------
1089d5ac3d36SDaniel Pereira
1090d5ac3d36SDaniel PereiraExistem muitos arquivos de cabeçalho em ``include/linux/`` que contêm várias
1091d5ac3d36SDaniel Pereiramacros que você deve usar em vez de escrever explicitamente alguma variante
1092d5ac3d36SDaniel Pereiradelas. Por exemplo, se você precisa calcular o comprimento de um array, aproveite
1093d5ac3d36SDaniel Pereiraa macro
1094d5ac3d36SDaniel Pereira
1095d5ac3d36SDaniel Pereira.. code-block:: c
1096d5ac3d36SDaniel Pereira
1097d5ac3d36SDaniel Pereira	#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
1098d5ac3d36SDaniel Pereira
1099d5ac3d36SDaniel Pereiraque é definida em ``array_size.h``.
1100d5ac3d36SDaniel Pereira
1101d5ac3d36SDaniel PereiraDa mesma forma, se você precisar calcular o tamanho de um membro de alguma
1102d5ac3d36SDaniel Pereiraestrutura, use
1103d5ac3d36SDaniel Pereira
1104d5ac3d36SDaniel Pereira.. code-block:: c
1105d5ac3d36SDaniel Pereira
1106d5ac3d36SDaniel Pereira	#define sizeof_field(t, f) (sizeof(((t*)0)->f))
1107d5ac3d36SDaniel Pereira
1108d5ac3d36SDaniel Pereiraque é definida em ``stddef.h``.
1109d5ac3d36SDaniel Pereira
1110d5ac3d36SDaniel PereiraTambém existem macros ``min()`` e ``max()`` definidas em ``minmax.h`` que fazem
1111d5ac3d36SDaniel Pereiraverificação estrita de tipos se você precisar delas. Sinta-se à vontade para
1112d5ac3d36SDaniel Pereiraexplorar os arquivos de cabeçalho para ver o que já está definido e não deve
1113d5ac3d36SDaniel Pereiraser reproduzido no seu código.
1114d5ac3d36SDaniel Pereira
1115d5ac3d36SDaniel Pereira
1116d5ac3d36SDaniel Pereira19) Modelines do editor e outros restos
1117d5ac3d36SDaniel Pereira---------------------------------------
1118d5ac3d36SDaniel Pereira
1119d5ac3d36SDaniel PereiraAlguns editores podem interpretar informações de configuração embutidas em
1120d5ac3d36SDaniel Pereiraarquivos de origem, indicadas por marcadores especiais. Por exemplo, o emacs
1121d5ac3d36SDaniel Pereirainterpreta linhas marcadas assim:
1122d5ac3d36SDaniel Pereira
1123d5ac3d36SDaniel Pereira.. code-block:: c
1124d5ac3d36SDaniel Pereira
1125d5ac3d36SDaniel Pereira	-*- mode: c -*-
1126d5ac3d36SDaniel Pereira
1127d5ac3d36SDaniel PereiraOu assim:
1128d5ac3d36SDaniel Pereira
1129d5ac3d36SDaniel Pereira.. code-block:: c
1130d5ac3d36SDaniel Pereira
1131d5ac3d36SDaniel Pereira	/*
1132d5ac3d36SDaniel Pereira	Local Variables:
1133d5ac3d36SDaniel Pereira	compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
1134d5ac3d36SDaniel Pereira	End:
1135d5ac3d36SDaniel Pereira	*/
1136d5ac3d36SDaniel Pereira
1137d5ac3d36SDaniel PereiraO Vim interpreta marcadores que parecem com isto:
1138d5ac3d36SDaniel Pereira
1139d5ac3d36SDaniel Pereira.. code-block:: c
1140d5ac3d36SDaniel Pereira
1141d5ac3d36SDaniel Pereira	/* vim:set sw=8 noet */
1142d5ac3d36SDaniel Pereira
1143d5ac3d36SDaniel PereiraNão inclua nenhum desses em arquivos de origem. As pessoas têm suas próprias
1144d5ac3d36SDaniel Pereiraconfigurações pessoais de editor, e seus arquivos de origem não devem
1145d5ac3d36SDaniel Pereirasubstituí-las. Isso inclui marcadores para indentação e configuração de modo.
1146d5ac3d36SDaniel PereiraAs pessoas podem usar seu próprio modo personalizado, ou podem ter algum outro
1147d5ac3d36SDaniel Pereiramétodo mágico para fazer a indentação funcionar corretamente.
1148d5ac3d36SDaniel Pereira
1149d5ac3d36SDaniel Pereira
1150d5ac3d36SDaniel Pereira20) Montagem inline
1151d5ac3d36SDaniel Pereira-------------------
1152d5ac3d36SDaniel Pereira
1153d5ac3d36SDaniel PereiraEm código específico de arquitetura, pode ser necessário usar montagem inline
1154d5ac3d36SDaniel Pereirapara interagir com a funcionalidade da CPU ou da plataforma. Não hesite em
1155d5ac3d36SDaniel Pereirafazê-lo quando necessário. No entanto, não use montagem inline de forma
1156d5ac3d36SDaniel Pereiragratuita quando o C puder fazer o trabalho. Você pode e deve mexer em hardware
1157d5ac3d36SDaniel Pereiraem C quando possível.
1158d5ac3d36SDaniel Pereira
1159d5ac3d36SDaniel PereiraConsidere escrever funções auxiliares simples que encapsulem partes comuns de
1160d5ac3d36SDaniel Pereiramontagem inline, em vez de escrevê-las repetidamente com pequenas variações.
1161d5ac3d36SDaniel PereiraLembre-se de que a montagem inline pode usar parâmetros C.
1162d5ac3d36SDaniel Pereira
1163d5ac3d36SDaniel PereiraFunções grandes e não triviais de montagem devem ir para arquivos ``.S``, com
1164d5ac3d36SDaniel Pereiraprotótipos C correspondentes definidos em arquivos de cabeçalho C. Os
1165d5ac3d36SDaniel Pereiraprotótipos C para funções de montagem devem usar ``asmlinkage``.
1166d5ac3d36SDaniel Pereira
1167d5ac3d36SDaniel PereiraVocê pode precisar marcar sua instrução ``asm`` como ``volatile`` para impedir
1168d5ac3d36SDaniel Pereiraque o GCC a remova se o GCC não perceber efeitos colaterais. No entanto, você
1169d5ac3d36SDaniel Pereiranem sempre precisa fazer isso, e fazê-lo desnecessariamente pode limitar a
1170d5ac3d36SDaniel Pereiraotimização.
1171d5ac3d36SDaniel Pereira
1172d5ac3d36SDaniel PereiraAo escrever uma única instrução de montagem inline contendo várias instruções,
1173d5ac3d36SDaniel Pereiracoloque cada instrução em uma linha separada em uma string separada e termine
1174d5ac3d36SDaniel Pereiracada string, exceto a última, com ``\n\t`` para indentar corretamente a
1175d5ac3d36SDaniel Pereirapróxima instrução na saída de montagem:
1176d5ac3d36SDaniel Pereira
1177d5ac3d36SDaniel Pereira.. code-block:: c
1178d5ac3d36SDaniel Pereira
1179d5ac3d36SDaniel Pereira	asm ("magic %reg1, #42\n\t"
1180d5ac3d36SDaniel Pereira	     "more_magic %reg2, %reg3"
1181d5ac3d36SDaniel Pereira	     : /* outputs */ : /* inputs */ : /* clobbers */);
1182d5ac3d36SDaniel Pereira
1183d5ac3d36SDaniel Pereira
1184d5ac3d36SDaniel Pereira21) Compilação condicional
1185d5ac3d36SDaniel Pereira--------------------------
1186d5ac3d36SDaniel Pereira
1187d5ac3d36SDaniel PereiraSempre que possível, não use condicionais do pré-processador (#if, #ifdef) em
1188d5ac3d36SDaniel Pereiraarquivos ``.c``; isso torna o código mais difícil de ler e a lógica mais difícil
1189d5ac3d36SDaniel Pereirade seguir. Em vez disso, use esses condicionais em um arquivo de cabeçalho que
1190d5ac3d36SDaniel Pereiradefina funções para uso nesses arquivos ``.c``, fornecendo versões de stub sem
1191d5ac3d36SDaniel Pereiraefeito no caso ``#else``, e então chame essas funções incondicionalmente nos
1192d5ac3d36SDaniel Pereiraarquivos ``.c``. O compilador evitará gerar qualquer código para as chamadas de
1193d5ac3d36SDaniel Pereirastub, produzindo resultados idênticos, mas a lógica permanecerá fácil de
1194d5ac3d36SDaniel Pereiraseguir.
1195d5ac3d36SDaniel Pereira
1196d5ac3d36SDaniel PereiraPrefira compilar funções inteiras fora do código, em vez de partes de funções
1197d5ac3d36SDaniel Pereiraou partes de expressões. Em vez de colocar um ``ifdef`` em uma expressão,
1198d5ac3d36SDaniel Pereiraextraia parte ou toda a expressão para uma função auxiliar separada e aplique a
1199d5ac3d36SDaniel Pereiracondicional a essa função.
1200d5ac3d36SDaniel Pereira
1201d5ac3d36SDaniel PereiraSe você tiver uma função ou variável que pode potencialmente ficar sem uso em
1202d5ac3d36SDaniel Pereirauma configuração específica, e o compilador avisaria sobre a definição ficar sem
1203d5ac3d36SDaniel Pereirauso, marque a definição como ``__maybe_unused`` em vez de envolvê-la em uma
1204d5ac3d36SDaniel Pereiracondicional do pré-processador. (No entanto, se uma função ou variável
1205d5ac3d36SDaniel Pereira*sempre* ficar sem uso, elimine-a.)
1206d5ac3d36SDaniel Pereira
1207d5ac3d36SDaniel PereiraDentro do código, quando possível, use a macro ``IS_ENABLED`` para converter um
1208d5ac3d36SDaniel Pereirasímbolo Kconfig em uma expressão booleana C e usá-la em uma condicional C
1209d5ac3d36SDaniel Pereiranormal:
1210d5ac3d36SDaniel Pereira
1211d5ac3d36SDaniel Pereira.. code-block:: c
1212d5ac3d36SDaniel Pereira
1213d5ac3d36SDaniel Pereira	if (IS_ENABLED(CONFIG_SOMETHING)) {
1214d5ac3d36SDaniel Pereira		...
1215d5ac3d36SDaniel Pereira	}
1216d5ac3d36SDaniel Pereira
1217d5ac3d36SDaniel PereiraO compilador reduzirá a condicional a um valor constante e incluirá ou
1218d5ac3d36SDaniel Pereiraexcluirá o bloco de código assim como com um ``#ifdef``, então isso não
1219d5ac3d36SDaniel Pereiraadicionará nenhum custo de runtime. No entanto, essa abordagem ainda permite
1220d5ac3d36SDaniel Pereiraque o compilador C veja o código dentro do bloco e verifique sua correção
1221d5ac3d36SDaniel Pereira(sintaxe, tipos, referências de símbolo etc.). Portanto, você ainda precisa usar
1222d5ac3d36SDaniel Pereiraum ``#ifdef`` se o código dentro do bloco referenciar símbolos que não existirão
1223d5ac3d36SDaniel Pereirase a condição não for atendida.
1224d5ac3d36SDaniel Pereira
1225d5ac3d36SDaniel PereiraNo final de qualquer bloco ``#if`` ou ``#ifdef`` não trivial (mais de algumas
1226d5ac3d36SDaniel Pereiralinhas), coloque um comentário após o ``#endif`` na mesma linha, indicando a
1227d5ac3d36SDaniel Pereiraexpressão condicional usada. Por exemplo:
1228d5ac3d36SDaniel Pereira
1229d5ac3d36SDaniel Pereira.. code-block:: c
1230d5ac3d36SDaniel Pereira
1231d5ac3d36SDaniel Pereira	#ifdef CONFIG_SOMETHING
1232d5ac3d36SDaniel Pereira	...
1233d5ac3d36SDaniel Pereira	#endif /* CONFIG_SOMETHING */
1234d5ac3d36SDaniel Pereira
1235d5ac3d36SDaniel Pereira
1236d5ac3d36SDaniel Pereira22) Não derrube o kernel
1237d5ac3d36SDaniel Pereira------------------------
1238d5ac3d36SDaniel Pereira
1239d5ac3d36SDaniel PereiraEm geral, a decisão de derrubar o kernel pertence ao usuário, e não ao
1240d5ac3d36SDaniel Pereiradesenvolvedor do kernel.
1241d5ac3d36SDaniel Pereira
1242d5ac3d36SDaniel PereiraEvite ``panic()``
1243d5ac3d36SDaniel Pereira*****************
1244d5ac3d36SDaniel Pereira
1245d5ac3d36SDaniel Pereira``panic()`` deve ser usado com cuidado e principalmente apenas durante a inicialização
1246d5ac3d36SDaniel Pereirado sistema. ``panic()`` é, por exemplo, aceitável ao ficar sem memória durante
1247d5ac3d36SDaniel Pereiraa inicialização e não ser possível continuar.
1248d5ac3d36SDaniel Pereira
1249d5ac3d36SDaniel PereiraUse ``WARN()`` em vez de ``BUG()``
1250d5ac3d36SDaniel Pereira**********************************
1251d5ac3d36SDaniel Pereira
1252d5ac3d36SDaniel PereiraNão adicione novo código que use nenhuma das variantes de ``BUG()``, como
1253d5ac3d36SDaniel Pereira``BUG()``, ``BUG_ON()`` ou ``VM_BUG_ON()``. Em vez disso, use uma variante de
1254d5ac3d36SDaniel Pereira``WARN*()``, preferencialmente ``WARN_ON_ONCE()``, e possivelmente com código de
1255d5ac3d36SDaniel Pereirarecuperação. O código de recuperação não é obrigatório se não houver uma
1256d5ac3d36SDaniel Pereiramaneira razoável de pelo menos recuperar parcialmente.
1257d5ac3d36SDaniel Pereira
1258d5ac3d36SDaniel Pereira"Sou preguiçoso para tratar erros" não é uma desculpa para usar ``BUG()``.
1259d5ac3d36SDaniel PereiraCorrupções internas graves sem como continuar ainda podem usar ``BUG()``, mas
1260d5ac3d36SDaniel Pereiraprecisam de uma boa justificativa.
1261d5ac3d36SDaniel Pereira
1262d5ac3d36SDaniel PereiraUse ``WARN_ON_ONCE()`` em vez de ``WARN()`` ou ``WARN_ON()``
1263d5ac3d36SDaniel Pereira************************************************************
1264d5ac3d36SDaniel Pereira
1265d5ac3d36SDaniel Pereira``WARN_ON_ONCE()`` geralmente é preferido em relação a ``WARN()`` ou
1266d5ac3d36SDaniel Pereira``WARN_ON()``, porque é comum que uma dada condição de aviso, se ocorrer,
1267d5ac3d36SDaniel Pereiraocorra várias vezes. Isso pode encher e sobrescrever o log do kernel e até
1268d5ac3d36SDaniel Pereiradiminuir o sistema o suficiente para que o registro excessivo vire um problema
1269d5ac3d36SDaniel Pereiraadicional.
1270d5ac3d36SDaniel Pereira
1271d5ac3d36SDaniel PereiraNão emita ``WARN`` levianamente
1272d5ac3d36SDaniel Pereira*******************************
1273d5ac3d36SDaniel Pereira
1274d5ac3d36SDaniel Pereira``WARN*()`` foi concebido para situações inesperadas, em que "isso nunca devia
1275d5ac3d36SDaniel Pereiraacontecer". Macros ``WARN*()`` não devem ser usadas para nada que se espere que
1276d5ac3d36SDaniel Pereiraaconteça durante a operação normal. Esses não são asserts de pré- ou pós-
1277d5ac3d36SDaniel Pereiracondição, por exemplo. Novamente: ``WARN*()`` não deve ser usado para uma
1278d5ac3d36SDaniel Pereiracondição que se espera que seja acionada facilmente, por exemplo, por ações do
1279d5ac3d36SDaniel Pereiraespaço do usuário. ``pr_warn_once()`` é uma alternativa possível, se você
1280d5ac3d36SDaniel Pereiraprecisar notificar o usuário sobre um problema.
1281d5ac3d36SDaniel Pereira
1282d5ac3d36SDaniel PereiraNão se preocupe com usuários de ``panic_on_warn``
1283d5ac3d36SDaniel Pereira*************************************************
1284d5ac3d36SDaniel Pereira
1285d5ac3d36SDaniel PereiraMais algumas palavras sobre ``panic_on_warn``: lembre-se de que
1286d5ac3d36SDaniel Pereira``panic_on_warn`` é uma opção disponível do kernel, e muitos usuários a
1287d5ac3d36SDaniel Pereirahabilitam. É por isso que existe um texto "Não emita WARN levianamente" acima.
1288d5ac3d36SDaniel PereiraEntretanto, a existência de usuários de ``panic_on_warn`` não é uma razão válida
1289d5ac3d36SDaniel Pereirapara evitar o uso judicioso de ``WARN*()``. Isso ocorre porque quem habilita
1290d5ac3d36SDaniel Pereira``panic_on_warn`` explicitamente pediu ao kernel para travar se um ``WARN*()``
1291d5ac3d36SDaniel Pereirafor disparado, e esses usuários devem estar preparados para lidar com as
1292d5ac3d36SDaniel Pereiraconsequências de um sistema que tem uma chance um pouco maior de travar.
1293d5ac3d36SDaniel Pereira
1294d5ac3d36SDaniel PereiraUse ``BUILD_BUG_ON()`` para assertivas em tempo de compilação
1295d5ac3d36SDaniel Pereira*************************************************************
1296d5ac3d36SDaniel Pereira
1297d5ac3d36SDaniel PereiraO uso de ``BUILD_BUG_ON()`` é aceitável e encorajado, porque é uma assertiva
1298d5ac3d36SDaniel Pereiraem tempo de compilação que não tem efeito em tempo de execução.
1299d5ac3d36SDaniel Pereira
1300d5ac3d36SDaniel PereiraApêndice I) Referências
1301d5ac3d36SDaniel Pereira-----------------------
1302d5ac3d36SDaniel Pereira
1303d5ac3d36SDaniel PereiraThe C Programming Language, Second Edition
1304d5ac3d36SDaniel Pereiraby Brian W. Kernighan and Dennis M. Ritchie.
1305d5ac3d36SDaniel PereiraPrentice Hall, Inc., 1988.
1306d5ac3d36SDaniel PereiraISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).
1307d5ac3d36SDaniel Pereira
1308d5ac3d36SDaniel PereiraThe Practice of Programming
1309d5ac3d36SDaniel Pereiraby Brian W. Kernighan and Rob Pike.
1310d5ac3d36SDaniel PereiraAddison-Wesley, Inc., 1999.
1311d5ac3d36SDaniel PereiraISBN 0-201-61586-X.
1312d5ac3d36SDaniel Pereira
1313d5ac3d36SDaniel PereiraManuais GNU - onde em conformidade com K&R e este texto - para cpp, gcc,
1314d5ac3d36SDaniel Pereiragcc internals e indent, todos disponíveis em https://www.gnu.org/manual/
1315d5ac3d36SDaniel Pereira
1316d5ac3d36SDaniel PereiraWG14 é o grupo de trabalho de padronização internacional para a linguagem de
1317d5ac3d36SDaniel Pereiraprogramação C, URL: http://www.open-std.org/JTC1/SC22/WG14/
1318d5ac3d36SDaniel Pereira
1319d5ac3d36SDaniel PereiraKernel CodingStyle, by greg@kroah.com at OLS 2002:
1320d5ac3d36SDaniel Pereirahttp://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
1321