soficer 0 20 мая, 2009 Опубликовано 20 мая, 2009 · Жалоба Народ, такая проблема. Необходимо при компиляции определить сколько раз вызывается функция (foo), а так же передать переменную из препроцессора(скрипта) в код программы. :1111493779: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 20 мая, 2009 Опубликовано 20 мая, 2009 · Жалоба #!/bin/sh COUNT=0 for FILE in *.c do CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` COUNT=`expr ${COUNT} + ${CURR}` echo -e "${FILE}\t:${CURR}\t:${COUNT}" done cat > foo_call_count.h << EOF #ifndef _FOO_CALL_COUNT_H #define _FOO_CALL_COUNT_H #define foo_call_count ${COUNT} #endif /*_FOO_CALL_COUNT_H*/ EOF Ну а дальше, делаете foo_call_count.h зависимым от всех с-файлов и генерируете его при помощи этого скрипта. UPD. Улучшенная версия с предварительной обработкой препроцессором (препроцессор убирает комментарии). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 21 мая, 2009 Опубликовано 21 мая, 2009 · Жалоба Спасибо за совет, будем посмотреть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 21 мая, 2009 Опубликовано 21 мая, 2009 · Жалоба Спасибо за совет, будем посмотреть Не совсем понятно как формируется выражение CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` Как я понял, последние два оператора проверяют синтаксис на наличие foo, но вот что делают первые два? :smile3046: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 22 мая, 2009 Опубликовано 22 мая, 2009 · Жалоба Не совсем понятно как формируется выражение CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` Как я понял, последние два оператора проверяют синтаксис на наличие foo, но не понятно что значит grep -vv , такое сочетание параметров я не нашел нигде. :smile3046: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 22 мая, 2009 Опубликовано 22 мая, 2009 · Жалоба Первый обрабатывает препроцессором файл, второй отбрасывает служебную инфу препроцессора (может не надо), 3 - выделяет все упоминания функции, 4 - исключает прототипы функции и подсчитывает оставшиеся. Строчку "echo -e "${FILE}\t:${CURR}\t:${COUNT}"" можно удалить (исключительно для отладочных целей), ещё желательно натравливать препроцессор на файл с полным комплектом ключей компиляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 25 мая, 2009 Опубликовано 25 мая, 2009 · Жалоба Спасибо, прояснилось. Как я понимаю этот скрипт надо вписать в makefile?. И еще, давно хотел спросить, запись типа #define _FOO_CALL_COUNT_H определяет файл FOO_CALL_COUNT.H, но как препроцессор знает что перед H надо ставить точку. Почему просто не написать #include <FOO_CALL_COUNT.H> :yeah: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 25 мая, 2009 Опубликовано 25 мая, 2009 · Жалоба p.s отвечаю не сразу. т.к дома нет инета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 120 25 мая, 2009 Опубликовано 25 мая, 2009 · Жалоба запись типа #define _FOO_CALL_COUNT_H определяет файл FOO_CALL_COUNT.H, но как препроцессор знает что перед H надо ставить точку.Препроцессор ничего не знает и не ставит. Определяется символ _FOO_CALL_COUNT_H и дальше идет проверка именно этого символа. Это программист сам для себя решает, что _FOO_CALL_COUNT_H относится к файлу foo_call_count.h. Кстати, имена, начинающиеся с подчеркивания зарезервированы за компилятором и стандартной библиотекой, во избежание неприятностей свои имена с подчеркивания лучше не начинать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 25 мая, 2009 Опубликовано 25 мая, 2009 · Жалоба Спасибо, прояснилось. Как я понимаю этот скрипт надо вписать в makefile?. И еще, давно хотел спросить, запись типа #define _FOO_CALL_COUNT_H определяет файл FOO_CALL_COUNT.H, но как препроцессор знает что перед H надо ставить точку. Почему просто не написать #include <FOO_CALL_COUNT.H> :yeah: Скрипт лучше поместить в отдельный sh-файл и запускать при необходимости (из мейкфайла) (не уверен но может и из makefile-а работать). Разберем конструкцию по строчкам: 1. #ifndef _FOO_CALL_COUNT_H проверяем не объявлен ли _FOO_CALL_COUNT_H, если не объявлен - п.2. Если обьявлен - значит этот заголовочный файл включен не в первый раз и значит его содержимое можно не обрабатывать. 2. #define _FOO_CALL_COUNT_H Это является стандартным обрамлением для заголовочных файлов. Кстати, имена, начинающиеся с подчеркивания зарезервированы за компилятором и стандартной библиотекой, во избежание неприятностей свои имена с подчеркивания лучше не начинать.Спасибо за замечание, учту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 25 мая, 2009 Опубликовано 25 мая, 2009 (изменено) · Жалоба Определяется символ _FOO_CALL_COUNT_H и дальше идет проверка именно этого символа. Это программист сам для себя решает, что _FOO_CALL_COUNT_H относится к файлу foo_call_count.h. То есть, компилятор у себя в "уме" держит некую таблицу в которой, допустим, строке _FOO_CALL_COUNT_H соответствует include <FOO_CALL_COUNT.H>? Скрипт лучше поместить в отдельный sh-файл и запускать при необходимости (из мейкфайла). Разберем конструкцию по строчкам: 1. #ifndef _FOO_CALL_COUNT_H проверяем не объявлен ли _FOO_CALL_COUNT_H. Т.е запуск скрипта с помощью команды sh (скрипт)? Хотел бы уточнить выражение (объявлен ли _FOO_CALL_COUNT_H), если следовать синтаксису С, то это запись (_FOO_CALL_COUNT_H FOO_CALL_COUNT.H ) или нет? Мне хотелось бы понять сам механизм. :) Изменено 25 мая, 2009 пользователем antiwin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 120 25 мая, 2009 Опубликовано 25 мая, 2009 · Жалоба То есть, компилятор у себя в "уме" держит некую таблицу в которой, допустим, строке _FOO_CALL_COUNT_H соответствует include <FOO_CALL_COUNT.H>?Нет никакой таблицы. Нет никакого соответствия. вот смотрите: foo.h: #ifndef FOO_H_INCLUDED__ #define FOO_H_INCLUDED__ ..... #endif //FOO_H_INCLUDED__ abc.c: #include "foo.h" .... #include "foo.h" Что происходит при компиляции abc.c? 1)удаляются все комментарии. 2)весь текст foo.h вставляется в те места, где был #include "foo.h". Все, #include исчезли, на их месте появился текст. 3) Теперь препроцессор проходит весь файл от начала до конца. В месте, где файл foo.h вставлен первый раз, он встречает строку #ifndef FOO_H_INCLUDED__. 4)Он ищет в своих списках символ FOO_H_INCLUDED__ и не находит его. Символ не определен. Условие выполнилось, препроцессор просматривает текст внутри условия. 5) тут он встречает строку #define FOO_H_INCLUDED__. Он вносит такой символ в свои списки - все, символ определен. 6) он просматривает файл дальше и доходит до места, где был второй #include "foo.h". Тут он снова встречает строку #ifndef FOO_H_INCLUDED__. 7) Он снова смотрит в своих списках и теперь уже находит там символ FOO_H_INCLUDED__. Условие не выполнилось, препроцессор выкидывает весь текст до #endif . Все, содержимое foo.h попало компилятору только один раз. Как мы обозвали этот символ - FOO_H_INCLUDED__ или FOO_H_ или SKIP_THIS_FILE или TIPA_TEST - препроцессору все равно. Это наша забота, чтобы в каждом заголовочном файле был определен уникальный символ. И проще всего это сделать, связав имя символа с именем файла. Чтобы понять смысл выражения "определен символ" - лучше всего прочитать документацию на препроцессор (не компилятор, а именно препроцессор - до компилятора эти символы не доходят). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 26 мая, 2009 Опубликовано 26 мая, 2009 (изменено) · Жалоба Это наша забота, чтобы в каждом заголовочном файле был определен уникальный символ... Я правильно понал, об'явление уникального символа предохраняет от повторной компиляции? А вроде бы у препроцессора есть функции на этот счет? Он ищет в своих списках символ FOO_H_INCLUDED__ ... Значит, что то вроде таблицы все та ки есть... За ссылку спасибо, как почитаю отпишусь немного отвлеченный вопрос. AT (ADDR (.text) + SIZEOF (.text)) SIZEOF вроде понятно-это размер секции, тогда ADDR-это начало? и что это за оператор AT?. И еще, в WinAvr есть папка с man, как вот эти man прочесть? Я думаю, что масса вопросов сразу бы отпала. Изменено 26 мая, 2009 пользователем antiwin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 120 26 мая, 2009 Опубликовано 26 мая, 2009 · Жалоба Я правильно понал, об'явление уникального символа предохраняет от повторной компиляции? А вроде бы у препроцессора есть функции на этот счет? Есть, но они не стандартизованы (насколько я помню) и обладают рядом недостатков. Вот на этом форуме второй ответ описывает их. А обертка из #ifndef #define #endif работает везде. Вот неплохое описаниеЗначит, что то вроде таблицы все та ки есть...Как это устроено внутри - не знаю, да это и не принципиально. Важно, что никаких таблиц соответствия имени символа и имени файла нет.немного отвлеченный вопрос. AT (ADDR (.text) + SIZEOF (.text)) Дежа-вю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
soficer 0 29 июня, 2009 Опубликовано 29 июня, 2009 (изменено) · Жалоба Привет всем, такой вот проблем: как можно узнать адрес в ОЗУ выше которого стек не "перерастет"? Это нужно сделать на этапе компиляции. И еще, можно ли в теле функции узнать тип возвращаемого значения т.е допустим определена функция void *foo(...), далее где то вызывается int *ptr=foo(...), как в теле foo узнать что это указатель на int? Изменено 29 июня, 2009 пользователем antiwin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться