реклама на сайте
подробности

 
 
10 страниц V  « < 3 4 5 6 7 > »   
Reply to this topicStart new topic
> Перенос кода из под ИАРа на WinAVR, возникают некоторые вопросы...
alx2
сообщение Nov 27 2008, 11:50
Сообщение #61


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(aesok @ Nov 27 2008, 09:14) *
The controlling expression of a switch statement shall have integer type.
И что? Тип char - тоже integer type, что не мешает ему иметь размер 8 бит...
Тут проблема совсем в другом: результат выражения (flags & 0xe0) всегда дает нули во всех байтах кроме младшего. Поэтому вменяемый оптимизатор должен выкинуть их вычисление из генерируемого кода. У меня так и происходит (см. выше). Почему этого не происходит у sonycman, непонятно...

Цитата(sonycman @ Nov 27 2008, 14:28) *
Но неужели слепое следование стандартам больших машин - это абсолютно правильно и на AVR? Неужели в вышеприведённом примере столь необходимо было следовать такому стандарту?
не "стандартам больших машин", а правилам языка C.
Цитата(sonycman @ Nov 27 2008, 14:28) *
А может существует какая-то опция, позволяющая отключать эту фичу?
Поверь, тебе это не нужно. Я слышал о компиляторах, у которых такая опция есть. Но писать программы с рассчетом на такую опцию - значит писать их не на языке C. То есть сразу теряется совместимость с любыми другими C компиляторами, у которых такой опции нет. Плюс периодически ломать голову над тем, почему результат выражения получился вот такой, а не такой, какой ожидался. Ты хочешь, чтобы у тебя (127 + 127) / 2 давало -1? smile.gif И все ради чего? Ради экономии пары процентов машинного кода?


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 13:35
Сообщение #62


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(alx2 @ Nov 27 2008, 15:29) *
Как ты получил такой код??? =8-( )
Скажи, пожалуйста, версию своего компилятора, с какой оптимизацией компилировался код и как определено byte.

byte определён как unsigned char.
Версия компилятора - 4.3.2 - последний релиз кандидат.
Оптимизациия Оs.
Полностью командные строки компилятора и линкера я приводил немного ранее.

Странно всё это...
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 16:52
Сообщение #63


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Rst7 @ Nov 27 2008, 10:56) *
вычисляется через 16 бит. Чтото не так.


Расмотрим пример (x = 20):
#define LCD_WIDTH 240

void lcdPrintText(PGM_P text, byte flags, unsigned char x, signed char y)
{
x = (LCD_WIDTH + x ) / 2;
}

Если расчеты выполняються в 16-битном виде то:
x = (240 + 20) / 2 = 260 /2 = 130.

Если в 8-битной то:
x = (240 + 20) / 2 = 4 /2 = 2.

Вы все еще хотите такую оптимизацию?

Анатолий.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 17:03
Сообщение #64


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



2aesok
Если у меня в программе операнд имеет тип char, то это значит, что ни при каких условиях не будет достигнуто переполнение.
Следуя вашей логике, можно и операнды типа word обрабатывать, расширяя до double word...
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 27 2008, 17:08
Сообщение #65


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(aesok @ Nov 27 2008, 18:52) *
Расмотрим пример

Все понятно. Просто я немного в другом стиле пишу, посему стараюсь ручками прикручивать в нужных местах принудительные касты. Давно это делаю на автоматизме, посему малость торможу.

Только не надо спрашивать, как это - "в другом стиле", на форуме выложенно достаточно, чтобы оценить кривость моих рук smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 17:18
Сообщение #66


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(sonycman @ Nov 27 2008, 20:03) *
2aesok
Если у меня в программе операнд имеет тип char, то это значит, что ни при каких условиях не будет достигнуто переполнение.

Я вам привел пример когда оба операнда имеют тип char, и происходит переполнение.

Цитата(sonycman @ Nov 27 2008, 20:03) *
Следуя вашей логике, можно и операнды типа word обрабатывать, расширяя до double word...


Компилятор это за вас не сделает, но если Вы не хотите получит ошибку переполнения, то Вы проанализируете исходные данные и формулы, и возжможно, да будете выполнять промежуточные расчеты с 32-битными числами, даже если операнды и результат 16-битные.

Анатолий.

Цитата(Rst7 @ Nov 27 2008, 20:08) *
Только не надо спрашивать, как это - "в другом стиле", на форуме выложенно достаточно, чтобы оценить кривость моих рук smile.gif


Компилятор тоже не может этого оценить. Но он стараеться генерировать правильный код в не зависимости от кривости рук програмиста, при этом код иногда получаеться более длинным.

Анатолий.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 18:22
Сообщение #67


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aesok @ Nov 27 2008, 21:18) *
Я вам привел пример когда оба операнда имеют тип char, и происходит переполнение.

Этот пример не имеет ничего общего с моим приложением.
Как не трудно было заметить из моего примера, константа LCD_WIDTH всегда складывается с отрицательным числом. Плюс операнды имеют значения, не допускающие переполнения.

Насчёт кривости рук - что вы скажете про то, откуда берутся странные предупреждения об обязательной инициализации и так инициализированных строковых массивов, расположенных в памяти программ?
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 19:49
Сообщение #68


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата
Этот пример не имеет ничего общего с моим приложением.
Как не трудно было заметить из моего примера, константа LCD_WIDTH всегда складывается с отрицательным числом. Плюс операнды имеют значения, не допускающие переполнения.



Это Ваш пример?
Код
#define    LCD_WIDTH 96
byte  lcdGetStringWidth(PGM_P text);

void  lcdPrintText(PGM_P text, byte flags, signed char x, signed char y)
  switch(flags & 0xe0)
  {
  case  TXT_CENTERED:
    if (x < 0)
    {
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
    }


(LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287]

Это чисто попещаеться в signed char? В unsigned char?

Цитата
Насчёт кривости рук - что вы скажете про то, откуда берутся странные предупреждения об обязательной инициализации и так инициализированных строковых массивов, расположенных в памяти программ?


Исходники GCC находяться здесь http://gcc.gnu.org/viewcvs/ Вы можете убрать мешающие Вам предупреждения сами.

Анатолий.

Сообщение отредактировал aesok - Nov 27 2008, 19:54
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 21:52
Сообщение #69


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aesok @ Nov 27 2008, 23:49) *
Это Ваш пример?
Код
#define    LCD_WIDTH 96
byte  lcdGetStringWidth(PGM_P text);

void  lcdPrintText(PGM_P text, byte flags, signed char x, signed char y)
  switch(flags & 0xe0)
  {
  case  TXT_CENTERED:
    if (x < 0)
    {
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
    }


(LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287]

Это чисто попещаеться в signed char? В unsigned char?

Нет. Но такие величины никогда не будут получены, так как операнды имеют значения, не допускающие переполнения. Не надо выдёргивать из контекста.
Цитата
Исходники GCC находяться здесь http://gcc.gnu.org/viewcvs/ Вы можете убрать мешающие Вам предупреждения сами.

Как? Я, у которого в программе переполнения на каждом шагу, должен исправлять глюки "умного" компилятора, который стараеться генерировать правильный код в не зависимости от кривости рук програмиста?
biggrin.gif

Что-то мне кажется, что мы ведём непродуктивный диалог.

После того, как было установлено, что приведение операндов к 16-ти битам делается для того, чтобы просто удовлетворять стандарту, вы хотите сказать, что это не так?
Что на самом деле этот шаг направлен на предотвращение переполнения?



Цитата(alx2 @ Nov 27 2008, 15:29) *
Как ты получил такой код??? =8-( )
Вот такой тестовый пример:
Код
int do_something(void);

void fff(char flags)
{
    switch(flags & 0xe0)
    {
        case 0x80:
            do_something();
    }
}
у меня компилируется вот в такой код:
Код
fff:
/* prologue: function */
/* frame size = 0 */
        andi r24,lo8(-32)
        cpi r24,lo8(-128)
        brne .L4
        rcall do_something
.L4:
        ret
при любой -O отличной от -O0. gcc-4.3.1.
Скажи, пожалуйста, версию своего компилятора, с какой оптимизацией компилировался код и как определено byte.

Добрался до компа. На всякий случай повторю повнятнее:
У меня WinAVR 20081118rc2 с компилятором GCC 4.3.2.
Оптимизация Os плюс ещё несколько "фишек".
Командная строка компилятора:
Код
avr-g++ -I"F:\Electronics\Projects\GNU\FanController\Headers" -Wall -g2 -gdwarf-2 -Os -fpack-struct -fshort-enums -mcall-prologues -funsigned-char -funsigned-bitfields -fno-exceptions -fno-threadsafe-statics -fno-inline-small-functions -ffunction-sections -mmcu=atmega88 -DF_CPU=10000000UL -MMD -MP -MF"Sources/main.d" -MT"Sources/main.d" -c -o"Sources/main.o" "../Sources/main.cpp"

Скомпилировал твой пример, вот что получилось:
Код
void do_something(char b)
{
    volatile static char a = b;
}

void fff(char flags)
{
    switch(flags & 0xe0)
    {
        case 0x80:
            do_something(0);
        case 0xc0:
            do_something(1);
    }
}


int main( void )
{


    fff(128);
...

и листинг:
Код
void fff(char flags)
{
    switch(flags & 0xe0)
    15be:    90 e0           ldi    r25, 0x00; 0
    15c0:    80 7e           andi    r24, 0xE0; 224
    15c2:    90 70           andi    r25, 0x00; 0
    15c4:    80 38           cpi    r24, 0x80; 128
    15c6:    91 05           cpc    r25, r1
    15c8:    21 f0           breq    .+8      ; 0x15d2 <fff(char)+0x14>
    15ca:    80 3c           cpi    r24, 0xC0; 192
    15cc:    91 05           cpc    r25, r1
    15ce:    29 f4           brne    .+10     ; 0x15da <fff(char)+0x1c>
    15d0:    02 c0           rjmp    .+4      ; 0x15d6 <fff(char)+0x18>
    {
        case 0x80:
            do_something(0);
    15d2:    80 e0           ldi    r24, 0x00; 0
    15d4:    e9 df           rcall    .-46     ; 0x15a8 <do_something(char)>
        case 0xc0:
            do_something(1);
    15d6:    81 e0           ldi    r24, 0x01; 1
    15d8:    e7 df           rcall    .-50     ; 0x15a8 <do_something(char)>
    15da:    08 95           ret

laughing.gif
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 22:22
Сообщение #70


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(sonycman @ Nov 28 2008, 00:52) *
Нет. Но такие величины никогда не будут получены, так как операнды имеют значения, не допускающие переполнения. Не надо выдёргивать из контекста.


Причем тут я? Я человек я мог бы Вас и понять. Я Вам показываю как думает тупая железка, тоесть компилятор. Где Вы ему сказали что " операнды имеют значения, не допускающие переполнения"?

Я Вам показывал вариант как это ему сказать:
x = (byte) (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;

И компилятор начал вычислять выражение как 8-битное.

Цитата(sonycman @ Nov 28 2008, 00:52) *
Как? Я, у которого в программе переполнения на каждом шагу, должен исправлять глюки "умного" компилятора, который стараеться генерировать правильный код в не зависимости от кривости рук програмиста?
biggrin.gif


Я не говорил что у Вас кривые руки, Я говорил что компилятор должен компилировать программу написанную даже кривыми руками, при этом программа должна работать в соответствии со стандартом, а в стандарте никаких указазий о скорости выполнения программы нет. Это оставленно на осмотрение разработчика компилятора.

Цитата(sonycman @ Nov 28 2008, 00:52) *
После того, как было установлено, что приведение операндов к 16-ти битам делается для того, чтобы просто удовлетворять стандарту, вы хотите сказать, что это не так?
Что на самом деле этот шаг направлен на предотвращение переполнения?


Я попытался на примере Вам показать почему так написан стандарт.


Цитата(sonycman @ Nov 28 2008, 00:52) *
Добрался до компа. На всякий случай повторю повнятнее:


Пока не знаю.

Анатолий.

Сообщение отредактировал aesok - Nov 27 2008, 22:28
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 22:46
Сообщение #71


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aesok @ Nov 28 2008, 02:22) *
Я попытался на примере Вам показать почему так написан стандарт.
Анатолий.

Хм... то есть, разработчики стандарта таким образом подстраховали все вычисления с операндами типа char? 07.gif
Мне всё равно трудно понять рациональность этого хода.
Потому, что ошибка с переполнением может возникнуть с любым по размеру операндом: 8, 16, 32, 64 и так далее бит.
Почему для 8-ми бит сделали исключение?

Цитата
(LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287]

Зачем "правильно" считать результат на 16-ти битах, если в конце концов он будет разрушен, будучи "обрезанным" и "запиханным" в signed char?
Если программист не продумал все варианты - ошибка обязательно вылезет всё равно.

Да... 05.gif
Но всё-же, спасибо за попытку всё объяснить. Извиняюсь за некоторое раздражение в моём тоне. beer.gif
В любом случае, стандарты придумывают весьма умные дядьки, не чета таким, как я 01.gif
Порой трудно бывает понять их мотивы. Воистину, пути их неисповедимы smile.gif
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 23:20
Сообщение #72


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(sonycman @ Nov 28 2008, 01:46) *
Хм... то есть, разработчики стандарта таким образом подстраховали все вычисления с операндами типа char? 07.gif
Мне всё равно трудно понять рациональность этого хода.
Потому, что ошибка с переполнением может возникнуть с любым по размеру операндом: 8, 16, 32, 64 и так далее бит.
Почему для 8-ми бит сделали исключение?


На самом деле исключение сделано для int. Это как бы тип по умолчанию,
разрядность int обычно равна разрядности регистров общего
назначения, что гарантирует максимальную производительность для этого типа.
Для AVR разрядность int больше разрядности регистра. Сделать int 8-битным
нельзя, в стандарте требуется - размерность указателя равна размерности int,
а 8-битный указатель это слишком мало.


Если быть совсем точным то avr-gcc имеет ключ:
-mint8 Use an 8-bit 'int' type

Его практическая ценность его мала, avr-libc не совместима с этим ключом, и
никогда не будет. Но если будете писать что нибудь маленькое, можете с ним
поиграться.

Цитата
Зачем "правильно" считать результат на 16-ти битах, если в конце концов он будет разрушен, будучи "обрезанным" и "запиханным" в signed char?
Если программист не продумал все варианты - ошибка обязательно вылезет всё равно.


Потому что в вашем примере обрезание рузультата до char произойдеи уже после деления, а для того чтобы результат деления на 2 влез в char делимое может иметь значение до char * 2, и для его хранения нужен int.

Цитата
Порой трудно бывает понять их мотивы. Воистину, пути их неисповедимы


На самом деле все очень просто, отладив несколько своих проектов Вы начнете думать как они...

Анатолий.

Сообщение отредактировал aesok - Nov 27 2008, 23:26
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 28 2008, 00:34
Сообщение #73


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aesok @ Nov 28 2008, 03:20) *
Потому что в вашем примере обрезание рузультата до char произойдеи уже после деления, а для того чтобы результат деления на 2 влез в char делимое может иметь значение до char * 2, и для его хранения нужен int.

Ну, не думаю, что компилер будет строить такие предположения.
Исходное положение:
Код
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
     e54:    e0 df           rcall    .-64; 0xe16 <lcdGetStringWidth(char const*)>
     e56:    21 2f           mov    r18, r17
     e58:    33 27           eor    r19, r19
     e5a:    27 fd           sbrc    r18, 7
     e5c:    30 95           com    r19
     e5e:    20 5a           subi    r18, 0xA0; 160
     e60:    3f 4f           sbci    r19, 0xFF; 255
     e62:    a9 01           movw    r20, r18
     e64:    48 1b           sub    r20, r24
     e66:    51 09           sbc    r21, r1
     e68:    ca 01           movw    r24, r20
     e6a:    62 e0           ldi    r22, 0x02; 2
     e6c:    70 e0           ldi    r23, 0x00; 0
     e6e:    17 d5           rcall    .+2606; 0x189e <__divmodhi4>

Смотрите, я убираю деление совсем, и вот что имеем:
Код
  x = (LCD_WIDTH + x - lcdGetStringWidth(text));
     e54:    e0 df           rcall    .-64; 0xe16 <lcdGetStringWidth(char const*)>
     e56:    0a c0           rjmp    .+20; 0xe6c <lcdPrintText(char const*, unsigned char, signed char,      
...
     e6c:    10 5a           subi    r17, 0xA0; 160
     e6e:    18 1b           sub    r17, r24

то есть весь код сводится к простым операциям. Заметьте - результат выражения по-прежнему будет:
Код
(LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287]

"невлезающим" в char, и "простая железка" может это просчитать как два пальца...
Но не хочет smile.gif

То же самое будет, если вывести деление во вторую строку:
Код
      x = (LCD_WIDTH + x - lcdGetStringWidth(text));
     e54:    e0 df           rcall    .-64; 0xe16 <lcdGetStringWidth(char const*)>
     e56:    10 5a           subi    r17, 0xA0; 160
      x /= 2;
     e58:    18 1b           sub    r17, r24
     e5a:    81 2f           mov    r24, r17
     e5c:    62 e0           ldi    r22, 0x02; 2
     e5e:    03 d5           rcall    .+2566; 0x1866 <__divmodqi4>

Первое и последнее выражения абсолютно эквивалентны по результату! Зато какие разные по размеру кода?
Тут явно что-то в этом делении... wacko.gif

Не первый раз замечаю, что, чем проще и короче строка программы в си, тем лучше получается у компилятора код.
Лучше разбивать одно длинное выражение на несколько простых. А так хочется извратиться позаковыристее, так, чтобы самому потом полчаса глаза таращить biggrin.gif
Задумывались бы чаще над этой проблемой те умные дядьки, которые всякие хитрые стандарты придумывают.
Уже 21 век на дворе, а мы всё плюсик на одной строке, а минусик - только на следующей, а то ещё у железки голова закружится... rolleyes.gif

Цитата(aesok @ Nov 28 2008, 03:20) *
На самом деле все очень просто, отладив несколько своих проектов Вы начнете думать как они...

Ну дай-то бог! cool.gif

ЗЫ: Всем спокойной ночи!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 28 2008, 01:08
Сообщение #74


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(sonycman @ Nov 28 2008, 02:34) *
То же самое будет, если вывести деление во вторую строку:
Код
  x = (LCD_WIDTH + x - lcdGetStringWidth(text));
тем самым в процессе присваивания неявно приводя результат типа int к типу x, т.е. signed char, что и советовал вам aesok:
Цитата(aesok @ Nov 28 2008, 00:22) *
x = (byte) (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
Так что, как видите, никаких чудес.
Цитата(sonycman @ Nov 28 2008, 02:34) *
Код
      x /= 2;
А тут деление signed char x на int 2 тоже с приведением результата. Tут компилятор смог сообразить и отбросить расширение.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
alx2
сообщение Nov 29 2008, 11:51
Сообщение #75


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(sonycman @ Nov 28 2008, 02:52) *
Код
    switch(flags & 0xe0)
    {
        case 0x80:
            do_something(0);
        case 0xc0:
            do_something(1);
    }
как показали эксперименты, как только в switch появляется второй case, в ассемблерном коде появляется вычисление незначащего старшего байта. Склоняюсь к выводу о недостатке оптимизатора в данном случае.

Цитата(sonycman @ Nov 28 2008, 03:46) *
Мне всё равно трудно понять рациональность этого хода.
Потому, что ошибка с переполнением может возникнуть с любым по размеру операндом: 8, 16, 32, 64 и так далее бит.
Почему для 8-ми бит сделали исключение?
Зачем "правильно" считать результат на 16-ти битах, если в конце концов он будет разрушен, будучи "обрезанным" и "запиханным" в signed char?
Если программист не продумал все варианты - ошибка обязательно вылезет всё равно.
Я не знаю точно, из каких соображений язык C сделан именно так, но выскажу свои соображения по этом поводу.
Во-первых, с последним утверждением согласен. Исходим из предположения, что кодер подумал, и ошибок в коде нет.

Во-вторых, я подозреваю, что вероятность выхода результата неких вычислений за границы диапазона (-128...127) намного выше чем диапазона (-32768...32767). Поэтому кодеру очень часто пришлось бы писать явное приведение к типу int, например писать (0 + a + b) / 2 вместо (a + b) / 2. Лично мне это бы не понравилось, т.к. во-первых, больше текста - больше вероятность ошибиться, а во-вторых, ухудшается читаемость кода. Почему тип приводится к int, а не к long или long long - я думаю, это компромисс между удобством и эффективностью. Случаи, когда диапазон значений int для вычислений недостаточен - достаточно редки чтобы явное приведение к long (long) не доставляло больших неудобств.

Наконец, что результат "в конце концов будет разрушен, будучи "обрезанным" и "запиханным" в signed char" - просто неверно, об этом aesok уже сказал.

Цитата(sonycman @ Nov 28 2008, 05:34) *
Код
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;

Код
      x = (LCD_WIDTH + x - lcdGetStringWidth(text));
      x /= 2;

Первое и последнее выражения абсолютно эквивалентны по результату!
Не эквивалентны. В первом случае преобразование к типу char производится перед делением, во втором - после. Например при LCD_WIDTH=96, x=32 и lcdGetStringWidth(text)=0 результат этих выражений будет разным.

Сообщение отредактировал alx2 - Nov 29 2008, 11:53


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post

10 страниц V  « < 3 4 5 6 7 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 10:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01558 секунд с 7
ELECTRONIX ©2004-2016