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

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> ARM7 сравнение компиляторов, провел небольшое исследование
Petka
сообщение Jul 6 2012, 07:45
Сообщение #31


Профессионал
*****

Группа: Свой
Сообщений: 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) ? Компилятор не может знать что это в вашем случае это не так =)
Go to the top of the page
 
+Quote Post
brag
сообщение Jul 6 2012, 07:54
Сообщение #32


Профессионал
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Petka
сообщение Jul 6 2012, 08:38
Сообщение #33


Профессионал
*****

Группа: Свой
Сообщений: 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. Это ничего не меняет.
Go to the top of the page
 
+Quote Post
brag
сообщение Jul 6 2012, 08:52
Сообщение #34


Профессионал
*****

Группа: Свой
Сообщений: 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;
Go to the top of the page
 
+Quote Post
Petka
сообщение Jul 6 2012, 09:39
Сообщение #35


Профессионал
*****

Группа: Свой
Сообщений: 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, то это очевидная ошибка программиста.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 6 2012, 09:43
Сообщение #36


Гуру
******

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



В "голых" Сях есть квалификатор restrict для указателей для подобных целей. В плюсах его нет.


--------------------
На любой вопрос даю любой ответ
"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
brag
сообщение Jul 6 2012, 10:21
Сообщение #37


Профессионал
*****

Группа: Свой
Сообщений: 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 sm.gif) почти всеми плюсовыми компилерами, правда да, в стандарте его нету
Go to the top of the page
 
+Quote Post
Petka
сообщение Jul 6 2012, 11:24
Сообщение #38


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(brag @ Jul 6 2012, 14:21) *
Тогда в случаи с next->prev=prev; prev->next=next; тоже нету явного указания компилятору, что prev может изменится. Ситуация аналогичная вроде? если next->prev == <cast...>&(prev->next) то это вероятно ошибка программиста.
...

Ситуация далеко не аналогичная. Просто прямое обращение по адресу и обращение двойное обращение по адресу.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:38
Рейтинг@Mail.ru


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