Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сделать рекурсивную функцию, которую компилятор сможет развернуть  (Прочитано 8179 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« : 05-01-2009 11:30 » 

Всем привет!
Вот такое задание Улыбаюсь :
Сделайте рекурсивную функцию, которую компилятор сможет развернуть. Обратите внимание, что вам необходимо проверить, что компилятор ее-таки развернул.

Мои наброски:
1.
Код:
template <int size>
__forceinline void inv(double d[])
{
d[size] = -d[size];
inv<size-1>(d);
}

template <>
__forceinline void inv<0>(double d[])
{
d[0] = -d[0];
}
2.
Код:
__forceinline int fact(int n)
{
if(n == 1)
return 1;
return n * fact(n-1);
}

Но по-моему компилятор их не разворачивает.
Так как в дисассемблере написано:
   inv<5>(d);
00F41584  lea         eax,[d]
00F41587  push        eax 
00F41588  call        inv<5> (0F41064h)
00F4158D  add         esp,4

   int f = fact(10);
00F4154E  push        0Ah 
00F41550  call        fact (0F41037h)
00F41555  add         esp,4
00F41558  mov         dword ptr [f],eax

Хоть я и не знаю ассемблера, но это явно вызов функции.
Еще пробовал
Код:
#pragma inline_recursion(on)
#pragma inline_depth(15)
Но эффект тот же.

p.s. MS visual studio 2008
« Последнее редактирование: 05-01-2009 12:39 от Антон__ » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 05-01-2009 11:43 » 

Антон__, компилятор развернуть рекурсивную функцию?
может речь идеть о макросах

зы в С я 0
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 05-01-2009 11:48 » 

Как я понял, всё-таки функцию.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #3 : 07-01-2009 09:47 » 

а если так?
Код:
template<size_t n>
size_t fact()
{
    return n * fact<n - 1>();
}

template<>
size_t fact<1>()
{
    return 1;
}

int main()
{
    std::cout << fact<10>();
    return 0;
}
Записан

Странно всё это....
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 07-01-2009 22:49 » 

LogRus, в дисассемблере то же самое.
Можно как-нибудь посмотреть изменённый компилятором код?
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 09-01-2009 16:37 » 

Антон__, а режим сборки? Дебаг? Релиз? Может опции оптимизации выключены.
Записан

Странно всё это....
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 09-01-2009 19:55 » 

Поставил релиз... теперь компилятор считает факториал на этапе компиляции)))
А вот с моей функцией вообще какая-то фигня:
   inv<5>(d);
01001035  fld         qword ptr [esp+38h]
И что это может значить? Не понял
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 10-01-2009 07:34 » 

Поставил релиз... теперь компилятор считает факториал на этапе компиляции)))
Ну а ты не этого хотел? Улыбаюсь

А вот с моей функцией вообще какая-то фигня:
   inv<5>(d);
01001035  fld         qword ptr [esp+38h]
И что это может значить? Не понял
кажется это загрузка числа в мат сопроцессор
Записан

Странно всё это....
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 10-01-2009 18:45 » 

Цитата
Ну а ты не этого хотел?
Ну это уже другое задание Улыбаюсь

Как я понял, цель задания - развернуть функцию.
Чтобы inv<5>(d)
Стало
d[0] = -d[0]
d[1] = -d[1]
d[2] = -d[2]
d[3] = -d[3]
d[4] = -d[4]
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #9 : 11-01-2009 05:12 » 

попробуй первоначальный вариант 2
но в релизе собрать, но насколько я помню рекурсивные функции не инлайнятся и замени параметры с double на size_t
Записан

Странно всё это....
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 11-01-2009 20:16 » 

Цитата
но насколько я помню рекурсивные функции не инлайнятся
Прочитал в msdn,  для этого надо:
#pragma inline_recursion(on)   //причем действует только на следующую за ней функцию
#pragma inline_depth(10)   

Цитата
попробуй первоначальный вариант 2
Его на этапе компиляции считает Улыбаюсь

Цитата
и замени параметры с double на size_t
А какая разница, это же unsigned int?

Переделал немного, теперь заработало. Улыбаюсь
В дисассемблере теперь много такого кода:
...
fstp        qword ptr [esp+330h]
fld         qword ptr [esp+328h]
fchs       
...
   
fchs, neg - это я так понимаю negative и float change sign.
А вот и код: Улыбаюсь
Код:
#include <iostream>
using namespace std;

#define NUM 100
#define type1 int
#define type2 double

#pragma inline_recursion(on)
#pragma inline_depth(NUM*2)

template <type1 size>
inline void inv(type2 d[])
{
d[size-1] = -d[size-1];
inv<size-1>(d);
}

template <>
inline void inv<1>(type2 d[])
{
d[0] = -d[0];
}


int main()
{
int i = 0;
cin >> i;
srand(i);

type2 d[NUM];
for(int i=0;i<NUM;i++)
d[i] = rand();

inv<NUM>(d);
for(int i=0;i<NUM;i++)
cout << d[i] << "\n";
    return 0;
}

LogRus, спасибо за помощь Улыбаюсь
Записан
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 11-01-2009 20:33 » 

А какая разница между
 - typedef T2 T1;
 - #define T1 T2
 - typedef struct T2
   {
   ...
   } T1
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #12 : 11-01-2009 21:23 » 

Антон__, а какая вообще разница между typedef и define?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Антон__
Помогающий

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 11-01-2009 21:43 » 

Антон__, а какая вообще разница между typedef и define?
А при чём тут это?
Записан
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 12-01-2009 04:28 » 

typedef создаёт синоним типа, этот синоним ведёт себя при компиляции точно так же, как его родитель

#define делает макроподстановку, и что получится при компиляции иногда оказывается сюрпризом, если не умеешь пользоваться дефайном )
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #15 : 12-01-2009 05:26 » 

Цитата
и замени параметры с double на size_t
А какая разница, это же unsigned int?

в большинстве  случаев никакой, но мне он больше нравится Улыбаюсь
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 12-01-2009 16:53 » 

Антон__, чтобы лучше понимать, почитай статьи Михалыча:
http://club.shelek.ru/viewart.php?id=269
http://club.shelek.ru/viewart.php?id=270
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines