|
ARM7 сравнение компиляторов, провел небольшое исследование |
|
|
|
Jul 6 2012, 07:45
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(brag @ Jul 6 2012, 11:18)  Интересно с какой? Если будет next==prev всеравно поля next->prev,prev->prev и next->next,prev->next будут иметь разные адреса. Если next==prev==this тогда this->prev=this; this->next=this; Чет никак не могу придумать, как можно добится разного поведения от этих двух разных реализаций... апд. сории,в коде перепутал местами, но сути это не меняет,компилится так же.должно быть так Код next->prev=prev; prev->next=next;
11a: e9d0 1200 ldrd r1, r2, [r0] 11e: 604a str r2, [r1, #4] 120: e9d0 1000 ldrd r1, r0, [r0] 124: 6001 str r1, [r0, #0] А если next->prev == &(prev->next) ? Компилятор не может знать что это в вашем случае это не так =)
|
|
|
|
|
Jul 6 2012, 07:54
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата А если next->prev == &(prev->next) ? Компилятор не может знать что это в вашем случае это не так =) &(prev->next) Имеет тип tormoz**, а next->prev tormoz* . просто так оно не может быть присвоено. Тогда уж и компилятор не должен ничего удалять в таком случаи: Код volatile int t; void f(char *v){ *v=3; t=4; *v=5; } Вдруг v=&t , он же не может этого знать. тем не менее: gcc-4.7.1Код 00000000 <_Z1fPc>: 0: f240 0300 movw r3, #0 4: f2c0 0300 movt r3, #0 8: 2204 movs r2, #4 a: 601a str r2, [r3, #0] c: 2305 movs r3, #5 e: 7003 strb r3, [r0, #0] 10: 4770 bx lr armcc-4.1Код 00000000 <_Z1fPc>: 0: 4a51 ldr r2, [pc, #324]; (148 <__sti___10_kernel_cpp+0x20>) 2: 2103 movs r1, #3;<<--- Хохма 4: 2104 movs r1, #4 6: 6011 str r1, [r2, #0] 8: 2105 movs r1, #5 a: 7001 strb r1, [r0, #0] c: 4770 bx lr
|
|
|
|
|
Jul 6 2012, 08:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(brag @ Jul 6 2012, 11:54)  &(prev->next) Имеет тип tormoz**, а next->prev tormoz* . просто так оно не может быть присвоено. Это программистом в явном виде так присвоено не может быть. А через приведение типов может быть как угодно. Цитата Ну тогда уж и компилятор не должен ничего удалять в таком случаи: Код volatile int t; void f(char *v){ *v=3; t=4; *v=5; } Вдруг v=&t , он же не может этого знать. тем не менее: Тут другой случай. v всегда указывает на одну и ту же ячейку памяти и запись в t ничего не может изменить. v может указывать куда угодно, хоть на t. Это ничего не меняет.
|
|
|
|
|
Jul 6 2012, 08:52
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Тоесть компилятор всегда перегружает переменную,если ранее была лябая запись в память? Хотя вот: Код char b[5]; int f(long long *c){ *c=1; b[2]=1;b[3]=2; return *c+b[3]; }
00000000 <_Z1fPx>: 0: 2300 movs r3, #0 2: 2201 movs r2, #1 4: f240 0100 movw r1, #0 8: e9c0 2300 strd r2, r3, [r0] c: f2c0 0100 movt r1, #0 10: 2301 movs r3, #1 12: 708b strb r3, [r1, #2] 14: 2302 movs r3, #2 16: 70cb strb r3, [r1, #3] 18: 2003 movs r0, #3 1a: 4770 bx lr Возвращает всегда 3. А вдруг c пересекается с b? тогда результат будет далеко не 3 Код ztest1.cpp: extern char b[5]; int f(long long *c); int main(){ printf("%d\n",f((long long*)&b)); return 0; }
g++ -O1 -c ztest.cpp g++ -O1 ztest1.cpp ztest.o result=33619971
g++ -O2 -c ztest.cpp g++ -O1 ztest1.cpp ztest.o result=3 2 файла, абы компилятор не видел реализации функции f;
|
|
|
|
|
Jul 6 2012, 09:39
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(brag @ Jul 6 2012, 12:52)  Тоесть компилятор всегда перегружает переменную,если ранее была лябая запись в память? Хотя вот: Код char b[5]; int f(long long *c){ *c=1; b[2]=1;b[3]=2; return *c+b[3]; } ...... Тут компилятор волен оптимизировать. т.к. char b не обьявлен как volatile т.е. нет указания компилятору что содержимое b может измениться. Поэтому если с указывает на b, то это очевидная ошибка программиста.
|
|
|
|
|
Jul 6 2012, 10:21
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата нет указания компилятору что содержимое b может измениться. Поэтому если с указывает на b, то это очевидная ошибка программиста. Тогда в случаи с next->prev=prev; prev->next=next; тоже нету явного указания компилятору, что prev может изменится. Ситуация аналогичная вроде? если next->prev == <cast...>&(prev->next) то это вероятно ошибка программиста. В случаи с long logn/массивом можт быть и не ошибка, а модификация какого-то поля с флагами таким образом, хотя и не красивая. Вобщем мутно как-то. Тот же прикол, но вместо long long подсунуть short - перегружает short всегда после любой модификации памяти. restrict вероде поддерживается(или заменяется на пробел, как и register  ) почти всеми плюсовыми компилерами, правда да, в стандарте его нету
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|