Цитата(ArtDenis @ Nov 16 2012, 09:41)

AHTOXA, Указатель на нестатическую функцию член класса в с++ - это не настоящий указатель. Его структура и размер зависят от компилятора. Поэтому чтобы узнать адрес ф-ции, надо выяснить где именно в структуре этого указателя "сидит" конкретно адрес для перехода.
Я понимаю это. Потому и говорил не об указателе на функцию-член, а об её адресе. Но вот нестандартность такого решения - это действительно плохо.
Цитата(ArtDenis @ Nov 16 2012, 09:41)

А зачем вообще нужна нестатическая функция для процесса? Всё равно каждый процесс существует в единственном экземпляре.
Чтобы обращаться к членам класса. Чтобы инициализировать их в конструкторе. Чтобы обращаться к унаследованным функциям класса, в конце концов. Короче, чтоб инкапсуляция

Цитата(ReAl @ Nov 16 2012, 02:19)

Не надо адрес функции-члена...
Ладно, ладно

Сделал вариант с виртуальным exec().
В процессе работы обратил внимание, что TKernelAgent::cur_proc() - private. Мне непонятно такое недоверие к потомкам TKernelAgent:)
Пришлось выкручиваться так:
Код
TBaseProcess* base = const_cast<TBaseProcess*>(get_proc(cur_proc_priority()));
вместо тривиального
Код
TBaseProcess* base = cur_proc();
Обратил внимание, что gcc довольно своеобразно понимает атрибут noreturn. Он перестаёт восстанавливать испорченные регистры, но всё равно сохраняет их!

За счёт этого, кстати, вариант с виртуальным exec не проигрывает по стеку варианту с вызовом Slon.exec() из SlonProc::exec().
Хотя нет, всё равно проигрывает. Там же вызов через виртуальный транк...
В общем, вот, смотрите/критикуйте:
CODE
#ifndef VIRTUALPROCESS_H_
#define VIRTUALPROCESS_H_
#include <scmRTOS.h>
namespace OS
{
class BaseVirtualProcess : public TBaseProcess, public TKernelAgent
{
public:
INLINE_PROCESS_CTOR BaseVirtualProcess(
stack_item_t * StackPoolEnd
, TPriority pr
#if scmRTOS_DEBUG_ENABLE == 1
, stack_item_t * aStackPool
#endif
) : TBaseProcess(
StackPoolEnd
, pr
, launch_exec
#if scmRTOS_DEBUG_ENABLE == 1
, aStackPool
#endif
)
{
}
protected:
OS_PROCESS virtual void exec() { for(;;){} };
private:
OS_PROCESS static void launch_exec()
{
for(;;) // eliminate compiler warning
{
TBaseProcess* base = const_cast<TBaseProcess*>(get_proc(cur_proc_priority()));
// TBaseProcess* base = cur_proc(); // private!
BaseVirtualProcess* proc = static_cast<BaseVirtualProcess*>(base);
proc->exec();
}
}
};
template<TPriority pr, size_t stack_size>
class VirtualProcess : public BaseVirtualProcess
{
public:
INLINE_PROCESS_CTOR VirtualProcess()
: BaseVirtualProcess(&Stack[stack_size/sizeof(stack_item_t)]
, pr
#if scmRTOS_DEBUG_ENABLE == 1
, Stack
#endif
)
{
}
private:
stack_item_t Stack[stack_size/sizeof(stack_item_t)];
};
} // namespace OS
#endif /* VIRTUALPROCESS_H_ */
Если бы я знал, что такое электричество...