Misra-C — Padrão para software em C

Em 27/05/2010, em Linguagem C, por Sergio Prado

MISRA-C é um padrão de desen­volvi­mento de soft­ware em lin­guagem C desen­volvida pela mesma que dá seu nome, a Motor Indus­try Soft­ware Reli­a­bil­ity Asso­ci­a­tion. Este padrão tem foco em sis­temas embar­ca­dos auto­mo­tivos, mas suas práti­cas podem ser exten­di­das tam­bém para out­ras areas, como equipa­men­tos médi­cos e aeroe­s­pa­ci­ais.

Seu prin­ci­pal obje­tivo é pro­mover um con­junto de mel­hores práti­cas para o desen­volvi­mento de soft­ware seguro e portável em lin­guagem C. Foi ini­cial­mente pub­li­cado em 1998, e mel­ho­rado no decor­rer dos anos. A segunda e mais atual edição saiu em 2004, e foi enti­t­u­lada de “Guide­lines for the use of the C lan­guage in crit­i­cal sys­tems”, e desde então vem sendo uti­lizada por empre­sas de vários ramos que desen­volvem soft­ware embar­cado.

Infe­liz­mente o doc­u­mento não está disponível de forma gra­tuita, e quem quiser con­hecer a fundo a norma pre­cisa fazer um inves­ti­mento para adquiri-laMas bas­tam algu­mas pesquisas no Google para encon­trar bas­tante infor­mação rel­e­vante à respeito do assunto.

Padrões de desenvolvimento

Antes de falar do padrão, vamos comen­tar sobre as moti­vações para usá-lo.

A lin­guagem C é uma das lin­gua­gens mais poderosas e flexíveis que exis­tem. E é por isso que ela é extrema­mente pop­u­lar em sis­temas embar­ca­dos. Se bem uti­lizada, tem ótima per­for­mance, pode gerar um código bem pequeno e facilita bas­tante o acesso ao hard­ware. Mas o prob­lema esta exata­mente em como começamos a frase ante­rior: “Se bem utilizada…”.

A lin­guagem C nas mãos de pro­gra­madores inex­pe­ri­entes pode ser um prob­lema. Sua flex­i­bil­i­dade é uma faca de dois gumes, pois dá poderes extras ao desen­volve­dor, que talvez ainda não esteja preparado para usá-los.

E é por isso que os padrões de soft­ware exis­tem. Para nos aju­dar a usar esta fer­ra­menta de pro­gra­mação (no nosso caso a lin­guagem C) da forma mais cor­reta pos­sível, segundo a norma, através de deter­mi­nadas regras.

O padrão MISRA-C:2004

Voltando ao padrão, o MISRA-C:2004 con­tém 141 regras divi­di­das em 21 cat­e­go­rias. Destas 141 regras, 121 são man­datórias e 20 são recomen­dadas. E para o código ser “MISRA-C Com­pli­ance”, pre­cisa estar de acordo com todas as 141 regras, sem exceção.

Infe­liz­mente não temos espaço aqui para apre­sen­tar e dis­cu­tir cada uma das regras (e até seria bem cansativo fazer isso), então vamos ver algu­mas das mais impor­tantes (e con­tro­ver­sas) regras deste padrão.

Rule 1: All code shall con­form to ISO 9899 stan­dard C, with no exten­sions permitted.

Tradução: Todo código deve estar de acordo com o padrão ISO 9899, sem per­mis­são para o uso de extensões.

A primeira regra já é uma das mais polêmi­cas do padrão MISRA-C. O padrão ISO, tam­bém con­hecido como C99, não foi desen­volvido com foco em sis­temas embar­ca­dos, então como vamos ter um código para um sis­tema embar­cado auto­mo­tivo em con­formi­dade com o C99? Um soft­ware embar­cado nor­mal­mente requer algu­mas exten­sões para poder lidar dire­ta­mente com o hard­ware, como por exem­plo a palavra chave inter­rupt usada em alguns com­pi­ladores para definir uma rotina de trata­mento de inter­rupção. E isso pode ser um prob­lema para o padrão MISRA-C.

Neste caso, o padrão MISRA-C per­mite alguns desvios à regra para exten­sões à lin­guagem. Estas exten­sões devem estar bem doc­u­men­tadas e cen­tral­izadas, como por exem­plo, todos os aces­sos ao hard­ware em um único arquivo.

Rule 2.2: Source code shall only use /* … */ style comments.

Tradução: O código-fonte deve usar ape­nas comen­tários no estilo /* … */ 

Essa regra é mais para garan­tir um padrão de estilo de cod­i­fi­cação. Nada de usar os comen­tários de linha “//” her­da­dos do C++.

Rule 6.3: Type­defs that indi­cate size and signed­ness should be used in place of the basic types.

Tradução: Type­defs que indicam o tamanho e o sinal da var­iável devem ser usa­dos no lugar dos tipos básicos.

Esse padrão dev­e­ria ser seguido por todos que pre­ten­dem garan­tir a porta­bil­i­dade do código entre difer­entes arquite­turas de hard­ware. Por exem­plo, o código abaixo tem o obje­tivo de setar o bit 17 da vari­avel reg, considerando-se que int é um inteiro é de 4 bytes.

1
2
3
int reg;
 
reg |= 0x10000;

Quando por­ta­mos este código para uma arquite­tura de 16 bits, este código não vai fun­cionar, já que um inteiro terá ape­nas 2 bytes. Então o que o padrão sug­ere é o código abaixo:

1
2
3
4
5
typedef int int32;
 
int32 reg;
 
reg |= 0x10000;

Neste caso, quando por­ta­mos o código, basta mudar a declar­ação do type­def para o tipo cor­reto de um inteiro de 32 bits, por exemplo:

1
typedef long int32;

Rule 8.1: Func­tions shall have pro­to­type dec­la­ra­tions and the pro­to­type shall be vis­i­ble at both the func­tion def­i­n­i­tion and call.

Tradução: Funções devem ter seus pro­tóti­pos declar­a­dos e visíveis à sua definição e às suas chamadas.

Se a função é usada ape­nas no arquivo em que é declar­ada, o ideal é declarar seu pro­tótipo no ini­cio do arquivo. Se a função é usada em out­ros arquivos/módulos, o ideal é declarar seu pro­tótipo em um arquivo de header e incluí-lo em todos os mod­u­los onde a função é declar­ada e usada. 

Rule 9.1: All auto­matic vari­ables shall have been assigned a value before being used

Tradução: Todas as var­iáveis automáti­cas (locais) devem ter um valor atribuido antes de serem usadas.

Esta regra pode evi­tar muitos erros. Declarou uma var­iável local, inicialize-a. Declarou um buffer, use mem­set ou bzero para inicializá-lo. 

Rule 14.1: There shall be no unreach­able code.

Tradução: Não deve exi­s­tir código que nunca é executado.

A maio­ria dos com­pi­ladores hoje, quando con­fig­u­rado para otimizar por tamanho, acaba removendo do binário códi­gos que nunca são exe­cu­ta­dos. Mas até para mel­ho­rar a leitura, é sem­pre bom fazer uma limpeza em códi­gos que nunca são exe­cu­ta­dos, como o else do código abaixo:

1
2
3
4
5
6
7
void initBuffer(char *buffer, unsigned int size)
{
    if (size >= 0)
        bzero(buffer, size);
    else
        logError("Tamanho invalido!");
}

A função logEr­ror() nunca será exe­cu­tada já que size é uma var­iável sem sinal, por­tanto nunca será menor que zero.

Rule 16.2: Func­tions shall not call them­selves, either directly or indirectly

Tradução: Funções não podem chamar elas mes­mas direta ou indiretamente.

Você quer ver as con­se­quên­cias de um stack over­flow? Use funções recur­si­vas! Recursão pode ser às vezes uma solução ele­gante, mas con­some muitos recur­sos de memória e proces­sa­mento. Evite e busque soluções alternativas.

Rule 16.10: If a func­tion returns error infor­ma­tion, then that error infor­ma­tion shall be tested.

Tradução: Se uma função retorna infor­mações de erro, este erro deve ser checado.

Esta regra deve ser sem­pre seguida. Já vi muito código por aí chamando mal­loc() mas não ver­i­f­i­cando o resul­tado. Depois per­dem horas para debugar o código.

Rule 20.4: Dynamic heap mem­ory allo­ca­tion shall not be used

Tradução: Alo­cação dinâmica de memória não deve ser usada.

OK, na minha opinião esta é a regra mais polêmica do padrão. Alo­cação dinâmica de memória pode ser a causa da maio­ria (e dos piores) bugs da sua apli­cação. Frag­men­tação de memória e mem­ory leak são os prin­ci­pais cul­pa­dos. Mas às vezes pre­cisamos do mal­loc() para resolver alguns prob­le­mas. Minha sug­estão: use com muito cuidado e ape­nas como último recurso.

Rule 49: Tests of a value against zero should be made explicit, unless the operand is effec­tively Boolean.

Tradução: Ver­i­ficar se uma var­iável está zer­ada deve ser feito de forma explicita, a não ser que o operando seja booleano.

Bom, logo de cara vou dizer que entendo os motivos, mas dis­cordo desta regra. O que vocês acham mais legível, o primeiro if (padrão MISRA-C) ou o segundo?

1
2
3
4
5
6
7
if (bufferVazio == 0) { /* padrao MISRA-C */
    return;
}
 
if (!bufferVazio) {
    return;
}

Rule 104: Non-constant point­ers to func­tions shall not be used.

Tradução: Pon­teiros não con­stantes para funções não devem ser usados.

Dis­cordo nova­mente! Em alguns casos, pon­teiros para funções podem ser uma solução bem ele­gante, prática e sem muitos cus­tos para o sis­tema. Por exem­plo, dá para se imple­men­tar uma rotina de trata­mento de uma máquina de esta­dos com 3 ou 4 lin­has de código usando pon­teiro para funções (o meu artigo sobre máquina de esta­dos fala sobre isso). 

Para finalizar, exis­tem muitas fer­ra­men­tas de análise estática de código que podem ser usadas para ver­i­ficar se um código é com­patível com o padrão MISRA-C como PC-LINT, CodeCheck e QA-C.

Ter um código com­patível com o padrão não sig­nifica ape­nas que você vai desen­volver um código mais seguro e portável. Sig­nifica tam­bém que você vai estar mudando sua forma de pro­gra­mar, nem sem­pre para mel­hor. Inter­prete, cri­tique e veja o que é mel­hor para a solução que esta bus­cando. Você não pre­cisa seguir à risca todas as regras, ape­nas aque­las que se apli­cam à seu pro­jeto. E pode não estar 100% com­pa­tivel com o padrão, mas vai com certeza ter mel­ho­rado a qual­i­dade do seu código. De qual­quer forma, vale a pena pelo menos dar uma olhada. O único risco que você vai cor­rer é apren­der um pouco mais com isso.

Um abraço,

Ser­gio Prado

VN:F [1.9.13_1145]
Rat­ing: 9.3/10 (3 votes cast)
Misra-C — Padrão para soft­ware em C, 9.3 out of 10 based on 3 ratings

Sem posts relacionados.

  • Fer­nando Barboza

    Oi Ser­gio!
        Parabéns pelos arti­gos e por dedicar parte do seu tempo em escreve-los.
        Uma pequena cor­reção na com­para­ção de códi­gos que fez, talvez até para deixar mais polêmica a com­para­ção entre os estilos.

    if (buffer­Vazio == 0) { /* padrao MISRA-C */
    return;
    }
     
    if (!buffer­Vazio) {
    return;
    }
        Para tornar os códi­gos equiv­a­lentes, fal­tou o detalhe do !.
     
    p.s. Tenho o cos­tume de usar o segundo estilo.

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • http://www.sergioprado.org ser­gio­prado

    Olá Fer­nando!

    Você tem razão. Post cor­rigido. Obri­gado pelo toque.

    E con­tinue acom­pan­hando o blog!

    Um abraço!

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • Alberto Fabi­ano

    Olá Sér­gio!
    Legal o posto, este é um dos meus assun­tos recor­rentes.
    Vale lem­brar que hoje há tam­bém o MISRA-C++ que tam­bém tem o mesmo foco, porém para a lin­guagem do tio Strous­trup! 
    [ ]s++;
    ./alberto –fabiano

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • Pingback: Tweets that mention Misra-C - Padrão para software em C -- Topsy.com

  • Alexan­dre Rodrigues

    Quanto à Rule 49, con­cordo que !buffer­Vazio é mais legível e coer­ente, con­siderando que esta var­iável é booleana ou está sendo usada como tal.  Afi­nal “VERDADEIRO” ou “NOT VERDADEIRO” é mais que intu­itivo para qual­quer desen­volve­dor.
    Quando se trata de uma var­iável que con­tenha um número, como tam­Buffer, vejo muitos prob­le­mas quando usada desta forma. Neste caso pre­firo o padrão MISRA (tam­Buffer == 0).
    Um caso que vejo causar muita con­fusão é o uso do !str­cmp ou !mem­cmp. Estas funções foram cri­adas com três retornos exata­mente para ter­mos as três situ­ações pos­síveis str1 < str2, str1 = str2 e str1 > str2. Acho que não cabe usar­mos o NOT neste caso, prin­ci­pal­mente por !str­cmp sig­nificar exata­mente str1 = str2. É só pen­sar­mos nos resul­ta­dos que podemos exper­i­men­tar ao ter­mos um pro­gra­mador ini­ciante tra­bal­hando no nosso pro­jeto ten­tando enten­der o que o pro­gra­mador ante­rior quis dizer com esta com­para­ção. Afi­nal, “NOT str­cmp” sig­nifica que as strings são iguais?
    No mais, parabéns Ser­gio, grande amigo. Con­tinua com­pe­tente, inter­es­sado e dis­posto a ensi­nar o que sabe. Nossa área anda um tanto car­ente de profis­sion­ais assim.

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • Poloni

    Alexan­dre, a van­tagem de se voltar um valor igual a zero tem van­ta­gens na otimiza­ção, já que você tem instruções em Assem­bly que resolve as com­para­ções em ape­nas um ciclo.
    If (tamanho == 0) equiv­ale à if (!tamanho). Se o com­pi­lador for “esper­t­inho” ele notará que é a mesma coisa. Por­tanto, colo­car explici­ta­mente é inter­es­sante. Isso vale inclu­sive para booleano.
    if (bool_var == false) é mel­hor e mais rápido do que if (bool_var == true). A com­para­ção por zero nor­mal­mente é resolvida em um ciclo.

    Com relação a Rule 20.4 alguns sis­temas opera­cionais em tempo real resolve esse prob­lema de uma forma bem inter­es­sante. Quem tiver um tempo, dêem uma lida nesse artigo http://www.embedded.com/design/222300428;jsessionid=50P5LPREJXGYTQE1GHPSKHWATMY32JVN?pgno=1. Quem quiser ir direto ao assunto, vá a página 3.

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • alex

    Parabens pelo site.
    acho que você dev­e­ria apon­tar as fontes pois já havia lido exata­mente o que você pub­li­cou
    em out­ros sites espe­cial­iza­dos. abraço

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • http://www.sergioprado.org ser­gio­prado

    Olá Alex,

    Você tem toda razão. As regras do padrão MISRA-C que usei neste post tirei dos links abaixo:

    http://www.embedded.com/columns/beginerscorner/9900659

    http://www.embedded.com/columns/technicalinsights/172301672

    Se você con­hecer mais alguma fonte inter­es­sante sobre o assunto deixe um comen­tário aqui.

    Um abraço!

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • http://www.icatel.com.br Rudolf Waller

    Sér­gio, antes de mais nada, parabéns pelo post :)

    A regra 49 cita que “unless the operand is effec­tively Boolean”. Como a var­iável Buffer­Vazio dos seus exem­p­los é booleana, ambos exem­p­los estariam cor­re­tos segundo esta regra, não? Pelo que entendi, o que esta regra evita é algo como “if(!Contador) …“
     
    Ainda no mesmo assunto, na minha opinião, se o com­pi­lador gera um código difer­ente para (!xxx) e (xxx!=0), já pas­sou da hora de tro­car de com­pi­lador ;)
     
    Abraços,
    Rudolf

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
    • http://www.sergioprado.org ser­gio­prado

      Olá Rudolf,

      Ótima obser­vação. A minha inter­pre­tação é que a regra quis dizer que você não pre­cisa fazer uma com­para­ção explicita ape­nas se sua var­iável for do tipo boolean. O exem­plo abaixo é per­mi­tido pelo padrão MISRA-C:

      bool buffer­Vazio;

      if (buffer­Vazio) {
      return;
      }

      Veja que a var­iável “buffer­Vazio” é do tipo bool. O tipo bool está especi­fi­cado no padrão ANSI C99.

      Um abraço,

      Ser­gio Prado

      VA:F [1.9.13_1145]
      Rating: 0.0/5 (0 votes cast)
  • http://www.icatel.com.br Rudolf Waller

    Oi Ser­gio,
     
    Dei uma pesquisada e vi que as regras 49 e 104 que você citou é do MISRA-C:1998. Não achei o equiv­a­lente destas regras na ver­são de 2004.
     
    Abraços,
    Rudolf

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • Hugo Sobreira

    Caro Ser­gio,

    Parabens pela ini­cia­tiva, de fato sinto falta de arti­gos rela­ciona­dos ao tema na nossa lín­gua por­tuguesa.
    Venho tra­bal­hando com desen­volvi­mento de sis­temas críti­cos já há alguns anos e hoje uti­lizo a MISRA-C como padrão de cod­i­fi­cação. Vale à pena ressaltar a difer­ença entre padrão de cod­i­fi­cação e padrão de desen­volvi­mento (ou design). Para desen­volver sis­temas críti­cos é necess­sario ter estes padrões definidos. Inter­es­sante notar tam­bém que adop­tar uma padrão de cod­i­fi­cação não é ape­nas boa prática quando se trata de sis­temas críti­cos (SC): é mesmo uma obri­gação. Padrões de cod­i­fi­cação são requeri­dos por difer­entes nor­mas que defen­dem desen­volvi­mento de SC (veja a DO-178B, IEC-61508, EN-50128).
    Quanto ao padrão MISRA-C, os jus­ti­fica­ti­vas para cada regra são muito bem expli­cadas na própria norma, por isso recomendo sua leitura a qual­quer um que pense seri­amente em aplicá-la. Lá vc vai ver tam­bém que nem todas as regras são nor­ma­ti­vas, há tam­bém regras opcionais.

    O que tenho visto como exper­iên­cia geral é que MISRA-C não tem por propósito somente “edu­car” desen­volve­dores inex­pe­ri­entes. Desen­volver soft­ware para SC pode ser uma tarefa extrema­mente árdua pelo sim­ples fato de con­struções mais elab­o­radas da lin­guagem não serem permitidas.Tomando como exem­plo a regra comen­tada em seu artigo sobre alo­cação dinâmica de memória (regra 20.4, uma das requeri­das pela norma). Num sis­tema crítico, é impre­scindível saber a pri­ori quan­tos e quais são os recur­sos uti­liza­dos pela apli­cação. Mais que isso, é pre­ciso demon­strar, que a quan­ti­dade de memória uti­lizada nunca ultra­pas­sará o lim­ite disponível (suponha que o pro­grama falhe de uma maneira cat­a­stró­fica caso não haja memória disponível). Quando se usa alo­cação dinâmica de memória é extrema­mente difí­cil provar esta ‘pro­priedade’. Por­tanto MISRA-C fala muito tam­bém à comu­nidade de pro­gra­madores expe­ri­entes em C, mas que podem não estar dev­i­da­mente con­tex­tu­al­iza­dos as neces­si­dades da natureza deste tipo de aplicação.

    Abraços,
    Hugo Sobreira

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
    • http://www.sergioprado.org ser­gio­prado

      Olá Hugo!

      Seu comen­tário é quase um novo post…:)

      Obri­gado pelas dicas valiosas e con­tinue apare­cendo por aqui.

      Um abraço!

      VA:F [1.9.13_1145]
      Rating: 0.0/5 (0 votes cast)
  • Sér­gio MacGyver

    Caro xará,   :-)
     
    Pre­tendia comen­tar a regra 49, sobre os testes de var­iável zer­ada, mas vi que out­ros já tece­ram seus comen­tários. No entanto, após você acres­cen­tar um comen­tário recon­hecendo que o if (!buffer­Vazio) é per­mi­tido pelo MISRA-C, não con­sigo enten­der em quê reside sua dis­cordân­cia do padrão.
     
    Quanto à regra 20.4, sobre o dynamic heap mem­ory allo­ca­tion, creio que o padrão con­dena não a alo­cação dinâmica em si, mas o método uti­lizado (heap mem­ory).
    Exis­tem out­ros esque­mas de alo­cação dinâmica em que a região alocável é pre­vi­a­mente par­ti­cionada em blo­cos de tamanho fixo, sendo alguns menores e out­ros maiores. Quando um código solicita memória, tenta-se entre­gar um bloco que pos­sua tamanho igual ou pouco maior que o solic­i­tado, caso disponível. Há perda de memória por entregar-se mais do que se pediu, mas não há o famiger­ado prob­lema de frag­men­tação de memória, em que há memória sufi­ciente, mas toda “espal­hada” pelo heap.
    Descon­fio que seja jus­ta­mente o prob­lema de frag­men­tação que esteja na causa das fal­has comu­mente asso­ci­adas à alo­cação de memória. Além da falta de teste de retorno do mal­loc, claro.
     
    Por fim, con­cordo com sua dis­cordân­cia (pun intended) da regra 104. Sou adepto da pro­gra­mação ori­en­tada a even­tos (+maquinas de esta­dos) em sis­temas embar­ca­dos, e essa é a mel­hor forma de se imple­men­tar even­tos (com funções de call­back).
     
    Descon­fio que o colega Hugo Sobreira é um con­hecido meu que tra­bal­hou na Motorola e talvez con­heça o esquema de alo­cação que citei acima. Se for você mesmo, bom te ver por aqui, Hugo! (eu tra­bal­hava no pro­jeto CESAR-Motorola).
     
    Sér­gio, por favor, encam­inhe esso meu comen­tário pro email do Hugo. Obrigado!

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
    • http://www.sergioprado.org ser­gio­prado

      Olá xará! :)

      Com relação à regra 49, quando uma var­iável rep­re­senta um valor boolean, ou seja, que pode assumir ape­nas true (1) ou false (0), eu acho muito mais fácil de ler o código sem ter que com­parar com 0 ou 1, como exige o padrão. Com relação à regra 20.4, você fez uma ótima obser­vação. Ainda não tinha con­sid­er­ado esta hipótese. E o Hugo par­tic­ipa bas­tante do grupo sis_embarcados, do qual agora você tam­bém faz parte…:) Estou te enviando o email dele em PVT. Um abraço e con­tinue acom­pan­hando o blog!

      VA:F [1.9.13_1145]
      Rating: 0.0/5 (0 votes cast)
  • http://www.lfamorim.com Lucas Fer­nando Amorim

    Parabéns Ser­gio,

    Ficou muito bom o seu artigo, padroniza­ção de código é um assunto muito impor­tante que merece ser dis­cu­tido. Toda ini­cia­tiva de estiliza­ção é bené­fica, levando a uma maior manuten­abil­i­dade do software.

    Como sem­pre seu blog é uma exce­lente fonte de infor­mações úteis e profissionais.

    Abraço.

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • http://murilo.wordpress.com murilo

    Esse exem­plo da regra 49.
    bufferVazio não é um booleano, mesmo que declar­ado como um int?
    Quero dizer, acho que essa regra diz para que não façamos algo do tipo:
    if (!buffer_len)
    e que façamos
    if (buffer_len == 0) 
    o que é muito mais legível, o sig­nifi­caria “se o tamanho do buffer for igual a 0″ ao invés de “se não tamanho do buffer“
    Agora para o exem­plo que você disse, ape­sar de bufferVazio ser provavel­mente um int, ele assume val­ores booleanos então !bufferVazio faz mais sen­tido “se o buffer não estiver vazio”.
    Um abraço,
    Murilo

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • http://www.sergioprado.org ser­gio­prado

    Olá Murilo, tudo bem?

    Seman­ti­ca­mente, “buffer­Vazio” é um booleano, mas sintati­ca­mente ele con­tinua sendo um int. O que o padrão quer nos dizer é que deve­mos fazer as com­para­ções explic­i­tas, ou seja, se dese­jamos ver­i­ficar se o buffer esta vazio, esta imple­men­tação está fora do padrão:

    if (buffer­Vazio) { … };

    E esta esta den­tro do padrão:

    if (buffer­Vazio == 1) { … };

    Eu con­cordo com você, e acho a primeira forma mais fácil de ler.

    Um abraço,

    Ser­gio Prado

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)
  • Sér­gio MacGyver

    Caros Sér­gio e Murilo,
    Pelo que entendi da regra 49, “Tests of a value against zero should be made explicit, unless the operand is effec tively Boolean”, no caso de bufferLen temos que fazer com­para­ções explíc­i­tas, pois é um con­ta­dor e não efe­ti­va­mente um booleano. Já no caso de buffer­Vazio, por se tratar efe­ti­va­mente de um booleano, ainda que implici­ta­mente um int, as com­para­ções if (buffer­Vazio) e if (!buffer­Vazio) são aceitas pelo MISRA-C.
    []s
    Sérgio

    VA:F [1.9.13_1145]
    Rating: 0.0/5 (0 votes cast)