Страница 1 из 1

Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 13:56:00
ARV
Случайно натолкнулся на следующее:

Код: Выделить всё

while(1){
   value=value*2+1;
   PORTD=value;
		
   int8_t i;
   for(i=1; i; i++) PORTD = i;
}
компилируется WinAVR в следующий код:

Код: Выделить всё

   while(1)
    {
        value=value*2+1;
  56:	80 91 00 01 	lds	r24, 0x0100
  5a:	88 0f       	add	r24, r24
  5c:	8f 5f       	subi	r24, 0xFF	; 255
  5e:	80 93 00 01 	sts	0x0100, r24
        PORTD=value;
  62:	8b b9       	out	0x0b, r24	; 11
  64:	81 e0       	ldi	r24, 0x01	; 1
		
		int8_t i;
		for(i=1; i; i++) PORTD = i;
  66:	8b b9       	out	0x0b, r24	; 11
  68:	8f 5f       	subi	r24, 0xFF	; 255
  6a:	fd cf       	rjmp	.-6      	; 0x66 <main+0x10>

0000006c <_exit>:
то есть цикл for получается БЕСКОНЕЧНЫМ. если тип переменной i сделать uint8_t, то цикл конечный:

Код: Выделить всё

    while(1)
    {
        value=value*2+1;
  5a:	99 0f       	add	r25, r25
  5c:	9f 5f       	subi	r25, 0xFF	; 255
        PORTD=value;
  5e:	9b b9       	out	0x0b, r25	; 11
  60:	81 e0       	ldi	r24, 0x01	; 1
		
		uint8_t i;
		for(i=1; i; i++) PORTD = i;
  62:	8b b9       	out	0x0b, r24	; 11
  64:	8f 5f       	subi	r24, 0xFF	; 255
  66:	e9 f7       	brne	.-6      	; 0x62 <main+0xc>
  68:	f8 cf       	rjmp	.-16     	; 0x5a <main+0x4>

0000006a <_exit>:
это баг компилятора или я чего-то недопонимаю?

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 14:17:35
ploop
С оптимизацией пробовали играться?
Точно, если отключить -Os будет компилироваться одинаковый код.

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 15:56:53
Pink-Pank
Интересно, как задефайнены Uint8_t и Int8_t... :roll: Как char и unsigned char?
А так да, похоже на глюк...

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 16:56:44
pcb
ARV писал(а):

Код: Выделить всё

		for(i=1; i; i++) PORTD = i;
это баг компилятора или я чего-то недопонимаю?
В первом варианте у тебя безнаковое число с безнаковой переменной (портд)

во втором случае у тебя изменяется знаковая перменная "И" и оно пихаецо в безнаковую переменную (портд)

Сделай преобразование типов:

Код: Выделить всё

uint8_t i;
for(i=1; i; i++) PORTD = ((int8_t)i);

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 17:01:34
ploop
Интересно, как задефайнены Uint8_t и Int8_t...
Дык посмотрите: http://www.nongnu.org/avr-libc/user-man ... tdint.html

pcb, тут явно глюк оптимизатора (или что-то другое хитрое). Без него всё работает верно.
Дело в том, что неважно, что куда пихается, цикл должен остановиться при обнулении переменной, а она в любом случае обнуляется.

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 17:11:38
urry
думаю, оптимизатор не совсем понял, что от него хотят. Можно попробовать static int8_t i; у него не хватит наглости выбросить глобальную.

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 17:20:19
Goodefine
Это не глюк, это undefined behaviour...

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 17:48:34
ploop
О, вот теперь понятно. Не знал о такой штуке.

Re: Баг AVR-GCC или я чего-то не понимаю?

Добавлено: Пт авг 15, 2014 21:43:36
ARV
Спасибо!!!