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