Цитата(Gogan @ Dec 28 2007, 15:21)

unsigned char a = 100;
float b = 20;
далее в программе
if( b < -a ){...}
так вот оказывается, в таком случаее условие выполняется.
Если кастовать вот так :
if( b < - (int) a ) {...}
тогда все ок. Объясните почему? Я не могу понять, что с чем сравнивается, если не кастовать, и почему так происходит?
На мой взгляд, компилятор не прав. Согласно стандарту С он должен оба эти if-а обрабаотывать одинаково и так, как второй. Есть такая штука, как integer promotion rules (integer promotions), согласно им любой целочисленный тип, который меньше int-а, должен приводиться к int перед вычислением выражений. Даже для
Код
char a,b,c;
a = b + c;
- привести к int, сложить, результат усечь и присвоить a.
Это требования к "абстрактной машине", дальше можно дать свободу и не делать приведение к int, но только в случае,
если от такого неделания результат не изменится.
В данном случае
-a это уже подвыражение с унарным минусом, перед его вычислением компилятору надо было привести a к int (что во втором примере сделано вручную), потом применить минус, потом, согласно правилам автоматических преобразований типов, результат привести к float и сравнить.
Так что тут компилятор не имел права делать
-a в пределах байта.
Цитата(Gogan @ Dec 28 2007, 20:33)

eeprom unsigned char edata[20][8]={{90,0,...},{}...};
unsigned int a;
далее в тексте
a=edata[0][0]+edata[0][1]<<8;
т.е. интегер хранится в двух первых байтах, сначала младший потом старший. Компилер выдал, что edata[0][1]<<8 получится в любом случае 0. Я переписал
a=(int)edata[0][0]+edata[0][1]<<8;
опять неправильно. Компилер не ругался, но результат был 90х256=23040. Правильным вариантом оказалось:
a=edata[0][0]+(int)edata[0][1]<<8;
Выбрось каку!!!Правильный компилятор (соответствующий стандарту) во всех трёх приведённых тобой вариантах должен был дать одинаковый результат, впрочем, не тот, который ты ожидаешь

Приведение к int делать вообще не нужно, оно должно было быть сделано согласно integer promotions самим компилятором.
А вот дальше - у оператора сложения приоритет выше, чем у операции сдвига (с моей точки зрения, приоритет сдвигов должен бы быть между приоритетами
*% и
+-, но K&R когда-то решили иначе и стандарт есть стандарт), поэтому
a + b << 8;должно вычисляться всегда как
( a + b ) << 8;А то, что хотелось сделать, следует записывать как
a + ( b << 8 );p.s. Не понимаю, как можно пользоваться компилятором, настолько не соответствующим стандарту...
Или он позиционируется как "компилятор С-
подобного языка программирования" ???