Resultado do concurso para ganhar o convite VIP

- por Sergio Prado

Categorias: Promoção Tags: ,

Gostaria de agradecer a todos que participaram do concurso para concorrer a um convite VIP para o Seminário C&C++ para Sistemas Embarcados 2010, que será realizado na próximo sábado (06 de novembro).

O objetivo da questão proposta era mostrar que uma sutil diferença entre a declaração de uma variável com signed ou unsigned pode fazer toda a diferença em uma simples expressão condicional.

Dos 27 participantes, 10 acertaram na resposta e na justificativa. Considerei como corretas todas as respostas que indicavam que o LED seria ou poderia ser apagado.

Alguns foram mais além, como o Henrique Pérsico Rossi, que considerou acertadamente que a implementação de um “char” é depedente do compilador, e não do padrão ANSI-C. Ou seja, para determinados compiladores, char é como padrão “signed char”, mas para outros pode ser “unsigned char”.

O Daniel Moreira Cestari também fez um comentário interessante, indicando que o tamanho da palavra da CPU pode influenciar no resultado, por exemplo, se o tamanho do int tiver o mesmo tamanho do char.

Para fazer o sorteio, numerei os acertadores de 1 a 10, e utilizei o método “Grito à distância para a esposa na sala”…) Pedi para ela escolher um número de 1 a 10, e ela escolheu o número 5, o Fernando Almeida. Parabéns Fernando!

Mas quem não ganhou o convite, não deixe de participar do evento. As inscrições vão até amanhã (03/11).

Como gostei bastante da resposta do Henrique, segue-a abaixo na integra:

/*************************************************/

Resposta: Depende!

Se o compilador implementar char como sendo do tipo signed (por padrão)…Não Acende! Se o compilador implementar char como sendo do tipo unsigned…Acende! Ou seja, é IMPLEMENTATION DEFINED.

Antes que uma operação aritmética seja executada, algumas conversões implícitas ocorrem ao longo do seu processamento. Uma delas é “balancing convertion”, a qual garante que todos operandos de uma operação sejam convertidos para um tipo em comum para que a operação possa ser executada. No entanto, para que esta conversão ocorra, faz-se necessária uma nova conversão implícita, integral promotion. Todos os valores do tipo short, char, enum e bit-field (conhecidos como small integer types) são convertidos para um dos seguintes tipos:

1) signed int, caso este tipo consiga representar o valor do tipo original (seja short, char, enum ou bit-field), ou

2) unsigned int, caso contrário.

Bem, dado o conceito acima, vamos aplicá-lo ao exercício proposto.

O compilador encontra os seguintes códigos:

1) chamada à função setLedStatus( LED_ON ) – O valor LED_ON (igual a 0xFF) é convertido para o tipo char, seja ele signed ou unsigned. Este processo é chamado de assigning convertion. Como char tem o tamanho de 1 byte, até aqui…sem problemas! 

2) teste condicional if ( status == LED_ON ) – Aqui aparece o problema! Dado que um operador relacional é encontrado (==, mas poderia ser !=, >, <, >=, <=, ou qualquer outro operador binário ou ternário), as regras de balancing convertion, como mencionado acima, são seguidas.

2.1) status poder ser convertido para int? Sim, pois trata-se de um tipo char. status é signed ou unsigned (lembre-se, implementation defined)? Vamos considerar uma arquitetura de 32 bits.

– se for signed: status assume o valor 0xFFFFFFFF, para continuar a representar o valor passado como argumento, -1 (value preserving em ação!)

– se for unsigned: status assume o valor 0x000000FF, para continuar a representar o valor passado como argumento, 255 (value preserving em ação!)

2.2) 0xFF é convertido para int. Considerando uma arquitetura de 32 bits, este valor é convertido para 0x000000FF.

Solução final:

1) se char for signed: if ( 0xFFFFFFFF == 0x000000FF ) => FALSE, portando NÃO ACENDE LED!!

2) se char for unsigned: if ( 0x000000FF == 0x000000FF ) => TRUE, portando ACENDE LED!!

/*************************************************/

Um abraço!

Sergio Prado

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.