Olá professor.
Minha intenção não é tentar ser chato, pointless nitpicking, ou qualquer coisa assim;
mas creio que dois exemplos presentes nos slides da aula de hoje de manhã (Semântica
Formal N) deixaram algumas pessoas confusas.
No exemplo 2:
i = 0 ;
i = i + i++;
i = 0 ;
i = i++ + i ;
i = 0 ,
i = i++ + i++;
Isto viola o item 6.5/2 do ISO 9899:1999, que diz:
2. Between the previous and next sequence point an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be read only to
determine the value to be stored. (70)
E no rodapé da página, a anotação 70 diz:
70) This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;
E, naturalmente o C++ mantém a mesma semântica; o item 5/4 do ISO 14882:2003 diz
essencialmente a mesma coisa, e dá como exemplo:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
Este tipo de construção é inclusive um FAQ: http://c-faq.com/ansi/experiment.html
Logo o código não é bem formado, pois a semântica da linguagem proíbe o que está
sendo feito.
Outro problema é o que foi dito do exemplo 3:
float q = 3.0 / 7.0 ;
if( q == 3.0/7.0 )
printf( "Tudo bem.\n" );
else
printf( "Tudo ruim.\n" ) ;
Foi dito que o código sempre imprime "Tudo ruim"; mas na verdade este código pode
imprimir qualquer das duas mensagens, basta que a representação de ponto flutuante em
questão seja capaz de representar a fração 3/7 da mesma forma tanto em double quanto
em float; se a implementação de ponto flutuante for de base 7, ou se float e double
forem iguais. De fato, float, double e long double podem ser todos idênticos (com o GCC
em i386 é fácil controlar o resultado do if usando a flag "-fshort-double"; é
possível que alguma arquitetura não possua tipos de ponto flutuante menores que o usado
por double, assim float sempre será o mesmo que double). O código do exemplo apenas
expressa uma característica de como a implementação se comporta, da mesma forma que:
unsigned i = 65535;
i++;
if (i)
printf( "Tudo bem.\n" );
else
printf( "Tudo ruim.\n" ) ;
Se int tiver 16 ou 32 bits, o resultado do teste pode ser diferente.
---
Daniel K. O.
Daniel,
concordo com a tua discussão dos exemplos; obrigado pelo trabalho. Basei mei pesquisa no padrão 14882:1998 e não achei nada lá. Da para ver que já sou mais velho, usando padrões antigas. LOL Acho que os exemplos ao menos servem a illustrar meu assunto na introdução: a dificuldade e a necessidade para semânticas claras e formais para as linguagens.
-- Marcus