Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Указатель на __noreturn функцию
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
gighack
как сабж сделать?
zltigo
Разумнее всего, так-же, как на любую другую а также на любую переменную. Указатель это адрес, адрес это имя.
Гглавное прежде всего самому себе не морочить голову вопросом замены call на jump ( это если моих телепатических возможностей хватило понять какой на самом деле вопрос был задан и зачем )
gighack
как именно? так вот
Код
void __noreturn (*pF)(void);

не работает. Пишет
Цитата
the type attribute "__noreturn" is not allowed on this declaration

И что значит не морочить голову заменой call на jump? Именно этой замены я и хочу добиться.
Savrik
Вы неправильно обьявляете указатель на функцию. Указатель на функцию имеет вид
Код
bool (*fPtr) (char)
- объявляет указатель fPtr, ссылающийся на функцию, которая возвращает логическое значение и принимает в качестве аргументов символ.
В общем виде будет такое применение
Код
bool retInt(char type);
int main()
{
bool (*fPtr)(char) = retInt;
cout<<retInt('A');
}


P.S. Извиняюсь, у Вас все правильно, недосмотрел....
zltigo
QUOTE (gighack @ Aug 5 2010, 10:20) *
И что значит не морочить голову заменой call на jump?

Вот именно это и значит - бессмысленная на 99,9% цель поставлена. Типа, сэкономить "один такт" и "один байт", один раз за все время работы программы.
Функция это функция и вызывается в общем случае call. Все остальное на откуп оптимизатору. Или прежде всего забыть, что это функция и оперировать ее адресом и переходить на него финтами. Вопрос зачем все это.
gighack
Все дело в стеке. Это ключевой момент в реализации модели состояний программы (см. аттач)
zltigo
QUOTE (gighack @ Aug 5 2010, 12:26) *
Это ключевой момент в реализации модели состояний программы (см. аттач)

Посмотрел совсем мельком. Смысла написанного особого не понял. За обильную смесь из 'C' и asm( "...." ) на IAR надо вообще руки отрывать, ибо оптимизацию сносит по полной программе. Относительно нормально такое только GCC переваривает. Для большинства компиляторов asm( ) это жуткая заплатка только для крайних случаев.
Вообще похоже Вы пытаетесь изобрести велосипед setjmp()/longjmp() а то и просто switch() smile.gif.
Если вдруг где-то чего-то действительно жмет, то несколько десятков строчек на ASM, тем более в ядре системы дело правильное. А пытаться замучать конкретный компилятор, дабы он сгенерил нечто конкретное, что Вам хочется увидеть дело не правильное.
Savrik
Перечитал первый и свой же пост - все таки я не понял назначения атрибута __noreturn. Попробуйте объявить указатель без него
Код
  void (*pF)(void);
zltigo
QUOTE (Savrik @ Aug 5 2010, 13:04) *
все таки я не понял назначения атрибута __noreturn.

Так никто не понял и главное компилятор smile.gif, как я полагаю, Автору мечталось, что с указателем на __noreturn компилятор должен будет проникнуться глубиной замысла и вместо вызова функции изобразить jump smile.gif.

Ink
А это ничего, вообще, что локальные переменные (в т.ч. временные, созданные компилятором) так же могут лежать на стеке? И их будет разное кол-во в этих функциях. Вы перейдете на другую подпрограмму, она выкинет другое кол-во переменных со стека при возврате и улетит вникуда...
gighack
Цитата(zltigo @ Aug 5 2010, 13:53) *
Смысла написанного особого не понял.

Поясню на примере как было раньше:
Код
char waitingSelfProgAck = 1;
__noreturn void main(void)
{
    MoveIvt(TO_BL_SECTION);
    InitUsart();
    InitProtocol();
    InitTimer();
    while(1)
    {
        if(waitingSelfProgAck)
            CheckTimer();
        if(ReceiveUsart())
            ProtocolHandler();
    }
}

Код
extern char waitingSelfProgAck;
void ProtocolHandler(void)
{
    if(IsReceivedCompleteAndCorrect())
    {
        switch(MsgType())
        {
        case MT_HELLO:
            waitingSelfProgAck = 0;
            ...
            break;
        case MT_ERR:
            if(waitingSelfProgAck)
                ...
            else
                ...
            break;
        /* Some other message handlers
        ...
        */
        }
    }
}

здесь происходит смешение обработчиков разных состояний - в одной функции main оказываются инициализация, проверка таймера (нужная только до получения некоторых сообщений) и обработка входа. То же самое в ProtocolHandler. Программа должна обрабатывать один набор сообщений до подключения программатора и другой - после. Т.е. при такой организации программы в ней появляются лишние - не существующие с точки зрения логики программы - связи. В модели состояний их нет.
Цитата(zltigo @ Aug 5 2010, 13:53) *
asm( ) это ... заплатка
В случае с переходами - да. Поэтому я и спрашиваю как сделать указатель на __noreturn функцию, чтобы убрать ассемблерную вставку.


Цитата(Savrik @ Aug 5 2010, 14:04) *
Попробуйте объявить указатель без него
Код
  void (*pF)(void);
Тогда при вызове pF() будет генерироваться call вместо jump


Цитата(zltigo @ Aug 5 2010, 14:19) *
как я полагаю, Автору мечталось, что с указателем на __noreturn компилятор должен будет проникнуться глубиной замысла и вместо вызова функции изобразить jump smile.gif.
Да, именно так я и написал в третьем посте.
zltigo
Вы высосали проблему "смешения" из пальца и теперь лезете в бутылку ради того, дабы ее "решить". Тот-же конечный автомат в main() не есть зло. Хочется красоты? В Вашем распоряжении операционные с вытесняющей многозадачностью. Хочется "на коленке" - уже писал - set/longjmp().

gighack
Цитата(Ink @ Aug 5 2010, 14:50) *
А это ничего, вообще, что локальные переменные (в т.ч. временные, созданные компилятором) так же могут лежать на стеке? И их будет разное кол-во в этих функциях. Вы перейдете на другую подпрограмму, она выкинет другое кол-во переменных со стека при возврате и улетит вникуда...
Не понял. В функциях с __noreturn у меня нету локальных переменных, а возвращаемы значения в строках типа if(SomeF()) храняться в регистрах
zltigo
QUOTE (gighack @ Aug 5 2010, 14:13) *
Не понял. В функция с __noreturn у меня нету локальных переменных

Три раза ха sad.gif. Пока в моей маленькой программке нету...., в конкретном случае я посмотрел листинг и убедился, что нету... Потребуется компилятору и он создаст локальную переменную для собсвенных нужд и Вас не спросит, и правильно сделает.
gighack
zltigo, Вы не могли бы уточнить, как именно ассемблерные вставки влияют на оптимизацию?
zltigo
QUOTE (gighack @ Aug 5 2010, 15:03) *
zltigo, Вы не могли бы уточнить, как именно ассемблерные вставки влияют на оптимизацию?

Погано влияют. В общем случае компилятор о их поведении ничего не знает, посему должен исходить из того, что во вставке мог быть изменен любой регистр. Какая уж тут оптимизация после этого sad.gif. Для обхода такого эффекта обычно есть в компиляторах ряд INTRINSICS - минимально необходимый набор процессорозависимых вещей, для которых в противном случае пришлось-бы городить вставки ( пусть даже из одной команды __no_operation(), __sleep(),..... ) на ASM. Посему, если ДЕЙСТВИТЕЛЬНО нужен ASM, то все пишется на чистом ASM, ассемблируется и линкуется.
gighack
Поразмышлял я тут над стеком и локальными переменными и решил отказаться от __noreturn функций в пользу обычных и цикла. Поэтому вопрос можно считать закрытым. Всем спасибо за помощь!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.