|
скрипт + gcc |
|
|
|
 |
Ответов
|
Jun 29 2009, 07:49
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Привет всем, такой вот проблем: как можно узнать адрес в ОЗУ выше которого стек не "перерастет"? Это нужно сделать на этапе компиляции. И еще, можно ли в теле функции узнать тип возвращаемого значения т.е допустим определена функция void *foo(...), далее где то вызывается int *ptr=foo(...), как в теле foo узнать что это указатель на int?
Сообщение отредактировал antiwin - Jun 29 2009, 08:01
|
|
|
|
|
Jul 3 2009, 19:08
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(antiwin @ Jun 29 2009, 12:49)  Привет всем, такой вот проблем: как можно узнать адрес в ОЗУ выше которого стек не "перерастет"? Это нужно сделать на этапе компиляции. В общем случае это невозможно. Цитата(antiwin @ Jun 29 2009, 12:49)  И еще, можно ли в теле функции узнать тип возвращаемого значения т.е допустим определена функция void *foo(...), далее где то вызывается int *ptr=foo(...), как в теле foo узнать что это указатель на int? Что " это"?  foo выполняется до присваивания, поэтому во время ее выполнения ptr еще не существует. Функция "знает" только то, что передается ей в качестве аргументов. Что потом произойдет с возвращаемым ей значением, она знать не может. А позвольте полюбопытствовать, для чего нужно "знать" внутри функции, какому объекту будет потом присваиваться возвращаемое ей значение? Такое желание мне кажется довольно странным, и наводит на мысль, что на самом деле задача состоит в другом - обеспечении более строгой типизации. На C++ это решается множеством различных способов - например, вместо типа void* функция может возвращать экземпляр класса, содержащего методы преобразования указателя к нужному типу - но это никак не будет влиять на код функции. Или инстанцированием функции из шаблона - тут код функции будет сразу генериться с учетом нужного типа, но тип придется при каждом вызове указывать явно...
Сообщение отредактировал alx2 - Jul 3 2009, 19:10
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Jul 14 2009, 11:08
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(alx2 @ Jul 3 2009, 23:08)  В общем случае это невозможно. Да в общем случае ненадо, можно ли найти данные(в файлах lst, map...) или где еще позволяющие расчитать вершину стека.? Цитата(alx2 @ Jul 3 2009, 23:08)  А позвольте полюбопытствовать, для чего нужно "знать" внутри функции, какому объекту будет потом присваиваться возвращаемое ей значение? Вобщем все просто, хочется написать альтернативу malloc ибо представляется она мне очень "глупой", ну не видит она где heap, а где stack. Кроме простого выделения памяти хочеться организовать минимальный менеджер памяти, способный дефрагментировать память. Конечно, об универсальном проекте речь не идет, но хотябы для "mega" с ОЗУ>500 байт.  Цитата(Troll @ Jul 8 2009, 09:48)  А для чего это надо? И если уж работаете с указателями, то почему бы просто не выполнить явное преобразование типа Код int *ptr = (int*) foo(); В том и проблема, так как можно char* foo(), и int* foo(), и uin32_t* foo(), т.е заранее неизвестно какой тип указателя нужен.
Сообщение отредактировал antiwin - Jul 14 2009, 11:00
|
|
|
|
|
Jul 14 2009, 11:41
|

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

|
Цитата(antiwin @ Jul 14 2009, 14:08)  менеджер памяти, способный дефрагментировать память. Интересно, как вы собираетесь это реализовать? Выделил ваш менеджер участок с адреса, скажем, 110. Вернул указатель. Вы его запомнили. Потом он в процессе дефрагментации переместил этот участок на адрес, скажем, 100. Как он сообщит вашей программе, что старый указатель больше не действителен? А если вы его уже успели скопировать в три других указателя?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 16 2009, 08:42
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(Сергей Борщ @ Jul 14 2009, 15:41)  Интересно, как вы собираетесь это реализовать? Просто, в ячейку указателя записывается новый адрес и все. Адрес самого указателя то не меняется. Что бы видеть все указатели, в менеджере предусмотрена специальная структура в которой каждому указателю(его адресу) соответствует адрес блока данных. Эта вынужденая мера, так как при работе с указателем его значение меняется, а в этой структуре он постоянен. Когда же приходит время удалить блок начало этого бока берется в структуре. Цитата(Сергей Борщ @ Jul 14 2009, 15:41)  А если вы его уже успели скопировать в три других указателя? Ну тут ничего не сделаешь, как и в любом компиляторе рано или поздно приходиться самому контролировать. К тому же не вижу практического смысла таких действий, потенциальный источник ошибок. Цитата(gotty @ Jul 14 2009, 15:30)  Так делайте явное преобразование типа по месту, как это сделано в malloc К стати, пытался найти описание malloc и других встроенных функций, но кроме определения не нашел. Где же они все таки описанны.?
Сообщение отредактировал antiwin - Jul 16 2009, 09:00
|
|
|
|
|
Jul 16 2009, 09:34
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(antiwin @ Jul 16 2009, 12:42)  Просто, в ячейку указателя записывается новый адрес и все. Адрес самого указателя то не меняется. Что бы видеть все указатели, в менеджере предусмотрена специальная структура в которой каждому указателю(его адресу) соответствует адрес блока данных. А какой размер этого масива? Три? Десять? Сто? А.... Вы озадачите нас вопросом: Как во время компиляции узнать количество используемых указателей в работуещей программе?! Цитата(antiwin @ Jul 16 2009, 12:42)  Ну тут ничего не сделаешь, как и в любом компиляторе рано или поздно приходиться самому контролировать. К тому же не вижу практического смысла таких действий, потенциальный источник ошибок. Вы никогда не слашали про такую вещь как Двусвязный список? Цитата(antiwin @ Jul 16 2009, 12:42)  К стати, пытался найти описание malloc и других встроенных функций, но кроме определения не нашел. Где же они все таки описанны.? Не сочтите за рекламу: www.google.com Анатолий.
Сообщение отредактировал aesok - Jul 16 2009, 10:07
|
|
|
|
|
Jul 16 2009, 11:58
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(aesok @ Jul 16 2009, 13:34)  А какой размер этого масива? Три? Десять? Сто? А.... Вы озадачите нас вопросом: Кол-во указателей (размер массива) определяется на этапе компиляции, путем подсчета вызовов определенной функции, отвечающей за выделение памяти. Цитата(Сергей Борщ @ Jul 16 2009, 13:54)  Простите, а как же тогда передавать этот массив в функции? А почему бы это не делать в функции? Ведь так гораздо проще контролировать для чего выделяется память. Но даже если придется, то просто в дело вступает еще один указатель указываеющий на "исходный" а тот-на массив (его начало). Поправте, если ошибаюсь. Цитата(aesok @ Jul 16 2009, 13:34)  Не сочтите за рекламу: www.google.com Гуглился битый час, может не тот гугль, но так или иначе отсылает к avr-libc. А там ничего. Дайте нужную ссылку пожалуйста.
Сообщение отредактировал antiwin - Jul 16 2009, 11:45
|
|
|
|
|
Jul 17 2009, 09:05
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(aesok @ Jul 16 2009, 17:19)  объясните мне: Не во время компиляции, а как бы перед ней, т.е скриптом (или иначе) анализируется каждый файл (*.с) проекта где и подсчитывается сколько раз вызывается функция. Потом это число записывается в файл и далее идет сама компиляция. Просто весь процесс я обозвал компиляцией. Цитата(aesok @ Jul 16 2009, 17:19)  Под описанием я имел ввиду не описание в человеческом смысле, а в рамках С99, т.е тело функции. А в предложенных ссылках (за них спасибо) описанние именно в первом смысле. Цитата(Troll @ Jul 15 2009, 14:28)  Размер стека определяется программистом... Смысл задуманного как раз в том чтобы освободить программиста от такого "счастья".
|
|
|
|
|
Jul 17 2009, 10:19
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(antiwin @ Jul 17 2009, 13:05)  Не во время компиляции, а как бы перед ней, т.е скриптом (или иначе) анализируется каждый файл (*.с) проекта где и подсчитывается сколько раз вызывается функция. Потом это число записывается в файл и далее идет сама компиляция. Просто весь процесс я обозвал компиляцией. Если ф-я вызывается в цикле, то Ваш анализ будет условия циклов проверять и т. д.? Если условие цикла зависит от железа (перефирийных блоков)? Эмулировать все будете? У меня конечно нет точных сведений, но по-моему, такого хорошего эмулятора (кроме реального железа конечно) не существует.
|
|
|
|
|
Jul 17 2009, 10:59
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(smac @ Jul 17 2009, 14:19)  Если ф-я вызывается в цикле, если условие цикла зависит от железа ? Условия проверяться не будут, т.к кол-во комбинаций=n! очень велико уже при n=10, где n-кол-во условных операторов. Просто будет собираться статистика вызовов каждой функции, анализироваться есть ли вложенные функции.? По поводу циклов не понял, уточните, а лучше пример в коде. На счет железа, это если что то из порта приходит? В любом случае условия не проверяются см. выше. Цитата(Troll @ Jul 17 2009, 14:48)  От какого счастья Вы собрались освободить программиста таким способом? Освободить от "счастья" самому руками задавать стек путем написания скрипта, результаты работы которого передавать в проект до компиляции. P.S на связь выду только в Пндк.
|
|
|
|
|
Jul 17 2009, 15:33
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(antiwin @ Jul 17 2009, 14:59)  Условия проверяться не будут, т.к кол-во комбинаций=n! очень велико уже при n=10, где n-кол-во условных операторов. Просто будет собираться статистика вызовов каждой функции, анализироваться есть ли вложенные функции.? По поводу циклов не понял, уточните, а лучше пример в коде. На счет железа, это если что то из порта приходит? В любом случае условия не проверяются см. выше. Пример конечно гипотетический, но Код int i; char *p; for (i=0; i<MAX; i++) //запускаем цикл по i (ну допустим количество опросов датчика или т. п.) if (SOME_PIN_IS_LOW&&(i&0x01)) // если нужная нога - 0 и номер опроса нечетный, то просим памяти p= (char*)malloc(SOME_MEMORY); С одной стороны, если функция вызывается и возвращается обратно, то стек она освободит (допустим мы заведомо знаем сколько стека она отожрет), но в данном примере число вызовов malloc() и соответсвенно количество требуемой памяти будет определяться временем сохранения истинных условий, естественно количество вызовов может варьировться от 0 до MAX/2 раз. Определить хватит ли памяти можно только прогоном программы иначе никак. Сомневаюсь что Ваш анализатор справится с задачей "просто заглянув исходник". Конечно данный пример не показывает как можно "перелезть" через вершину стека, однако я думаю что он показателен в смысле того что нельзя заранее определить сколько памяти требуется. Можно также упомянуть вложенные прерывания (хотя перед использованием этого приема нужно крепко подумать), оценить частоту и количество вызовов, а также уровень вложенности, которых по C исходнику с помощью машины тоже вряд-ли реально. Наконец стоит вспомнить о рекурсивных функциях - какая глубина рекурсии потребуется можно сказать только при полностью известных исходных данных, т. е. в том случае когда собственно программа обрабатывает заранее известную информацию, и результат ее (программы) работы в принципе тоже известен. Например Код void some_recursive_func(int i, long int a, long int b); // некая рекурсивная функция char read_some_port(void); // функция чтения порта, возвращающая практически случайное число от 0 до 256 int main (void){ int i; long int a; i = (int)read_some_port(); // читаем в i значение порта some_recursive_func(i, a, a); // вызываем нашу рекурсивную функцию return; } void some_recursive_func(int i, long int a, long int b){ // собственно функция if (i>0){ // если i положительная, то уменьшаем ее --i; b=a++; // делаем что-то some_recursive_func (i, a, b); // вызываем функцию . Вопрос лишь в том соклько раз она вызовется (и соответсвенно сколько стека отъест)? } } Конечно приведенные примеры сильно утрированы, но они простые, а в реальности могут быть на порядки сложнее, поэтому в общем случае мое мнение таково - ни один анализатор не сможет оценить реальные потребности в памяти по C исходникам при сколько-либо сложной задаче (т. е. в том случае где это нужно).
|
|
|
|
|
Jul 23 2009, 08:31
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(smac @ Jul 17 2009, 19:33)  Сомневаюсь что Ваш анализатор справится с задачей "просто заглянув исходник". Конечно, приведенные примеры поставят в тупик анализатор, но если он истпользует уже скомпилированный файл т.е асмовый текст. При использовании исходников подобные проблемы я думаю решаемы. Конечно, и в этом случае алгоритм анализа получится довольно сложным, а в более общих случаях достаточно приблизительным, помимо этого придется анализировать все include и определенные даные . По большому счету это уже компилятор (препроцессор). Но все же... От использования исходных файлов останавливает то, что не у всех функций можно получить описание, таких как: malloc, sin random ( т.е встроенных-библиотечных)....Я эту тему чуть выше поднимал, но честно пока так и не разобрался где лежит их описание. P.S Буду очень благодарен за внесение ястности в этот вопрос.
Сообщение отредактировал antiwin - Jul 23 2009, 08:34
|
|
|
|
|
Jul 23 2009, 10:55
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(antiwin @ Jul 23 2009, 12:31)  Конечно, приведенные примеры поставят в тупик анализатор, но если он истпользует уже скомпилированный файл т.е асмовый текст. При использовании исходников подобные проблемы я думаю решаемы. ... Не вижу разници между асмовым текстом и сишным, ибо количество вызовов ни по одному ни по другому в тех примерах не определить, дальше обсуждать это бессмысленно. Просто мне кажется, что написание того анализатора что Вы задумываете - гораздо более сложная задача, чем написание хорошего программного эмулятора (симулятора). Если решать ее в общем случае (например для семейства процессоров), то ресурсов (имеются ввиду "человеко-часы") уйдет очень много. С другой стороны решение этой задачи в частном случае - оценка потребляемого конкретным кодом стека, тоже потребует приличного времени, при том что в частном случае она может быть решена предлагаемыми в теме способами с меньшими потерями "человеко-часов".
|
|
|
|
Сообщений в этой теме
antiwin скрипт + gcc May 20 2009, 08:51 gotty Код#!/bin/sh
COUNT=0
for FILE in *.c
do
CUR... May 20 2009, 09:14 antiwin Спасибо за совет, будем посмотреть May 21 2009, 05:45 antiwin Цитата(antiwin @ May 21 2009, 09:45) Спас... May 21 2009, 08:23  antiwin Цитата(antiwin @ May 21 2009, 12:23) Не с... May 22 2009, 06:24   antiwin Спасибо, прояснилось. Как я понимаю этот скрипт на... May 25 2009, 06:02    Сергей Борщ Цитата(antiwin @ May 25 2009, 09:02) запи... May 25 2009, 07:43     antiwin Цитата(Сергей Борщ @ May 25 2009, 11:43) ... May 25 2009, 11:11      Сергей Борщ Цитата(antiwin @ May 25 2009, 14:11) То е... May 25 2009, 14:33       antiwin Цитата(Сергей Борщ @ May 25 2009, 18:33) ... May 26 2009, 06:27        Сергей Борщ Цитата(antiwin @ May 26 2009, 09:27) Я пр... May 26 2009, 08:13    gotty Цитата(antiwin @ May 25 2009, 09:02) Спас... May 25 2009, 07:47  gotty Первый обрабатывает препроцессором файл, второй от... May 22 2009, 11:26 antiwin p.s отвечаю не сразу. т.к дома нет инета. May 25 2009, 07:39   gotty Цитата(antiwin @ Jul 14 2009, 14:08) В т... Jul 14 2009, 11:30    AHTOXA Наверное речь идёт о дефрагментации свободных учас... Jul 14 2009, 13:05     gotty Цитата(AHTOXA @ Jul 14 2009, 16:05) Наве... Jul 15 2009, 06:22             aesok Цитата(antiwin @ Jul 23 2009, 12:31) ....... Jul 23 2009, 10:16              antiwin Цитата(smac @ Jul 23 2009, 14:55) Не вижу... Jul 24 2009, 08:46               aesok Цитата(antiwin @ Jul 24 2009, 12:46) Разн... Jul 24 2009, 09:26                aesok call-used call-saved Jul 24 2009, 10:47                antiwin Цитата(aesok @ Jul 24 2009, 13:26) Анализ... Jul 27 2009, 08:52                 Сергей Борщ Цитата(antiwin @ Jul 27 2009, 11:52) Поче... Jul 27 2009, 09:00     Сергей Борщ Цитата(antiwin @ Jul 16 2009, 11:42) К то... Jul 16 2009, 09:54   alx2 Прошу прощения за молчание - я в отпуске, сюда заг... Jul 17 2009, 12:52    antiwin Цитата(alx2 @ Jul 17 2009, 16:52) А потом... Jul 21 2009, 10:05     Troll Цитата(antiwin @ Jul 21 2009, 17:05) Вот ... Jul 21 2009, 11:16     alx2 Цитата(antiwin @ Jul 21 2009, 15:05) Попу... Jul 21 2009, 19:52      antiwin Цитата(alx2 @ Jul 21 2009, 23:52) Если в ... Jul 22 2009, 08:29       alx2 Цитата(antiwin @ Jul 22 2009, 13:29) Да, ... Jul 22 2009, 14:10 Troll Цитата(antiwin @ Jun 29 2009, 13:49) И ещ... Jul 8 2009, 05:48 Troll Цитата(gotty @ Jul 15 2009, 13:22) Ну, ес... Jul 15 2009, 10:28 Troll ЦитатаСмысл задуманного как раз в том чтобы освобо... Jul 17 2009, 10:48 Troll Цитата(antiwin @ Jul 17 2009, 17:59) Осво... Jul 17 2009, 13:58
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|