Цитата(demiurg_spb @ Nov 19 2012, 06:52)

1) Мне вообще представленная ТС строка не нравится *(pph++)=~(*(pph-4));
приходится напрягать мозг чтобы понять что произойдёт тут и вспоминать точки следования

2) ИМХО так значительно прозрачнее
Код
pph[0] = ~pph[-4];
pph++;
Моя версия компилятора даёт один и тот же ассемблерный код для обоих вариантов 1 и 2.
while(pph!=&ph[8])
{
*(pph++)=~(*(pph-4));
98: 80 91 70 00 lds r24, 0x0070
9c: 80 95 com r24
9e: 80 93 74 00 sts 0x0074, r24
a2: 80 91 71 00 lds r24, 0x0071
a6: 80 95 com r24
a8: 80 93 75 00 sts 0x0075, r24
ac: 80 91 72 00 lds r24, 0x0072
b0: 80 95 com r24
b2: 80 93 76 00 sts 0x0076, r24
b6: 80 91 73 00 lds r24, 0x0073
ba: 80 95 com r24
bc: 80 93 77 00 sts 0x0077, r24
И сначала мне больше понравилась ваша версия 2, поскольку никаких предупреждений не было, а в моём варианте было предупреждение: operation on pph may be undefined - операция с pph может быть неопределенной.
Но присмотревшись к коду, я понял к чему относится предупреждение. По си коду указатель pph в процессе исполнения кода увеличивается на 4, а в листинге указатель кода никак не участвует, поскольку там цикл развернут и применена прямая адресация! Поэтому компилятор предупреждает, что если вы будете использовать pph дальше, то содержимое указателя может быть отлично от того, на что вы рассчитывали. Я считаю, что лучше пусть будет предупреждение просто как напоминание, что может произойти в дальнейшем.
А чудеса с оптимизацией продолжаются. Из такого си кода, больше ничего нет
int main(void) //LCD test
{
unsigned char *pph;
unsigned char *pdg;
while(1)
{
pdg=&dig[0];
pph=&ph[4];
while(pph!=&ph[8])
{
*(pph++)=~(*(pph-4));
}
}
}
получается такой ассемблерный листинг
int main(void) //LCD test
{
5e: e4 e7 ldi r30, 0x74 ; 116
60: f0 e0 ldi r31, 0x00 ; 0
pph=&ph[4];
while(pph!=&ph[8])
{
*(pph++)=~(*(pph-4));
62: 34 97 sbiw r30, 0x04 ; 4
64: 80 81 ld r24, Z
66: 34 96 adiw r30, 0x04 ; 4
68: 80 95 com r24
6a: 81 93 st Z+, r24
}
while((pdg)!=&dig[4]);
pph=&ph[4];
while(pph!=&ph[8])
6c: 80 e0 ldi r24, 0x00 ; 0
6e: e8 37 cpi r30, 0x78 ; 120
70: f8 07 cpc r31, r24
72: b9 f7 brne .-18 ; 0x62 <main+0x4>
74: 34 97 sbiw r30, 0x04 ; 4
76: f5 cf rjmp .-22 ; 0x62 <main+0x4>
Умереть-не встать: теперь компилятор решил не разворачивать цикл while. Не могу понять, по какой причине меняется генерируемый код - по воле левой ноги компилятора или я делаю что-то не так?