Do you have a question? Post it now! No Registration Necessary
Subject
- Posted on
IAR EC++ - как правильно?
- 12-09-2003
- Vladimir Vassilevsky
December 9, 2003, 3:00 pm

Hi All,
Хочется использовать указатель на функцию - член класса:
class NETWORK {
public:
void SetGain(u8);
void SetPhase(u8);
void SetParameter(void (NETWORK::*Set)(u8), u8);
};
void NETWORK::SetParameter(void (NETWORK::*Set)(u8), u8 param)
{
DoSomething();
(this->*Set)(param);
DoSomethingElse();
}
void main(void)
{
NETWORK network;
network.SetParameter(SetGain, 0);
network.SetParameter(SetPhase, 1);
}
Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
подобный вызов. Можно ли это обойти?
VLV
Хочется использовать указатель на функцию - член класса:
class NETWORK {
public:
void SetGain(u8);
void SetPhase(u8);
void SetParameter(void (NETWORK::*Set)(u8), u8);
};
void NETWORK::SetParameter(void (NETWORK::*Set)(u8), u8 param)
{
DoSomething();
(this->*Set)(param);
DoSomethingElse();
}
void main(void)
{
NETWORK network;
network.SetParameter(SetGain, 0);
network.SetParameter(SetPhase, 1);
}
Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
подобный вызов. Можно ли это обойти?
VLV

IAR EC++ - как правильно?
Tue, 09 Dec 2003 18:00:47 +0300 Vladimir Vassilevsky wrote to All:
VV> Хочется использовать указатель на функцию - член класса:
Такое желание должно быть оправдано - указатели на члены как правило более
"толстые" (оверхедные) и работать с ними менее удобно, чем с простыми
указателями.
VV> class NETWORK {
VV> public:
VV> void SetGain(u8);
VV> void SetPhase(u8);
VV> void SetParameter(void (NETWORK::*Set)(u8), u8);
VV> };
VV> void NETWORK::SetParameter(void (NETWORK::*Set)(u8), u8 param)
VV> {
VV> DoSomething();
VV> (this->*Set)(param);
Зачем так сложно писать? SetParameter ведь является членом класса, поэтому
писать this-> совсем необязательно.
VV> DoSomethingElse();
VV> }
VV> void main(void)
VV> {
VV> NETWORK network;
VV> network.SetParameter(SetGain, 0);
VV> network.SetParameter(SetPhase, 1);
Хм, разве SetGain и SetPhase видны в этой области видимости? По-моему такой
код не должен компилироваться. Могу спутать синтаксис, но должно выглядеть
примерно так:
network.SetParameter(&network.SetGain, 0);
Т.е. нужно передавать полную информацию - и об объекте, и о смещении.
VV> }
VV> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV> подобный вызов. Можно ли это обойти?
Не очень понятно, что там получается (вот если б на листинг со сгенеренным
кодом посмотреть), но, возможно, тут имеет смысл использовать какое-то другое
решение? Повторю - указатели на члены далеко не всегда лучшее решение, и часто
проще и эффективнее обойтись без них. В данном случае, например, поскольку
между первым и вторым параметрами функции SetParameter какой-то корреляции не
просматривается, и в точке вызова функция, вызываемая по указателю, указана
явно, то проще и правильнее вызвать функцию SetGain и потом SetParameter с
одним аргументом... Конечно, если условия задачи другие, то и решение должно
быть другим, но для того, чтобы что-то предложить, нужно быть в курсе условий
задачи.
VV> Хочется использовать указатель на функцию - член класса:
Такое желание должно быть оправдано - указатели на члены как правило более
"толстые" (оверхедные) и работать с ними менее удобно, чем с простыми
указателями.
VV> class NETWORK {
VV> public:
VV> void SetGain(u8);
VV> void SetPhase(u8);
VV> void SetParameter(void (NETWORK::*Set)(u8), u8);
VV> };
VV> void NETWORK::SetParameter(void (NETWORK::*Set)(u8), u8 param)
VV> {
VV> DoSomething();
VV> (this->*Set)(param);
Зачем так сложно писать? SetParameter ведь является членом класса, поэтому
писать this-> совсем необязательно.
VV> DoSomethingElse();
VV> }
VV> void main(void)
VV> {
VV> NETWORK network;
VV> network.SetParameter(SetGain, 0);
VV> network.SetParameter(SetPhase, 1);
Хм, разве SetGain и SetPhase видны в этой области видимости? По-моему такой
код не должен компилироваться. Могу спутать синтаксис, но должно выглядеть
примерно так:
network.SetParameter(&network.SetGain, 0);
Т.е. нужно передавать полную информацию - и об объекте, и о смещении.
VV> }
VV> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV> подобный вызов. Можно ли это обойти?
Не очень понятно, что там получается (вот если б на листинг со сгенеренным
кодом посмотреть), но, возможно, тут имеет смысл использовать какое-то другое
решение? Повторю - указатели на члены далеко не всегда лучшее решение, и часто
проще и эффективнее обойтись без них. В данном случае, например, поскольку
между первым и вторым параметрами функции SetParameter какой-то корреляции не
просматривается, и в точке вызова функция, вызываемая по указателю, указана
явно, то проще и правильнее вызвать функцию SetGain и потом SetParameter с
одним аргументом... Конечно, если условия задачи другие, то и решение должно
быть другим, но для того, чтобы что-то предложить, нужно быть в курсе условий
задачи.
--
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
We've slightly trimmed the long signature. Click to see the full one.

IAR EC++ - как правильно?
Tue Dec 09 2003 20:53, Harry Zhurov wrote to Vladimir Vassilevsky:
VV>> Хочется использовать указатель на функцию - член класса:
HZ> Tакое желание должно быть оправдано - указатели на члены как правило
HZ> более "толстые" (оверхедные) и работать с ними менее удобно, чем с
HZ> простыми указателями.
Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и после
вызова нужно сделать одинаковую вспомогательную работу. Кроме того,
cаму функцию-член надо вызывать в цикле несколько раз. Хочется
завернуть все это хозяйство в одну универсальную функцию, которой
передается указатель на член.
Конечно, вместо этого можно просто сделать switch из явных вызовов
посередине универсальной функции и передавать параметр для свича,
однако так делать некузяво.
VV>> (this->*Set)(param);
HZ> Зачем так сложно писать? SetParameter ведь является членом класса,
HZ> поэтому писать this-> совсем необязательно.
Обязательно. Если ты вызываешь нестатическую функцию-член класса через
указатель, то нужно передать указатель на класс.
VV>> network.SetParameter(SetGain, 0);
VV>> network.SetParameter(SetPhase, 1);
HZ> Хм, разве SetGain и SetPhase видны в этой области видимости?
Конечно.
VV>> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV>> подобный вызов. Можно ли это обойти?
HZ> Hе очень понятно, что там получается (вот если б на листинг со
HZ> сгенеренным кодом посмотреть),
Посмотрел. В RAM появляется статическая таблица указателей на вызываемые
функции-члены класса. Зачем - непонятно. Ведь это константные адреса.
VLV
VV>> Хочется использовать указатель на функцию - член класса:
HZ> Tакое желание должно быть оправдано - указатели на члены как правило
HZ> более "толстые" (оверхедные) и работать с ними менее удобно, чем с
HZ> простыми указателями.
Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и после
вызова нужно сделать одинаковую вспомогательную работу. Кроме того,
cаму функцию-член надо вызывать в цикле несколько раз. Хочется
завернуть все это хозяйство в одну универсальную функцию, которой
передается указатель на член.
Конечно, вместо этого можно просто сделать switch из явных вызовов
посередине универсальной функции и передавать параметр для свича,
однако так делать некузяво.
VV>> (this->*Set)(param);
HZ> Зачем так сложно писать? SetParameter ведь является членом класса,
HZ> поэтому писать this-> совсем необязательно.
Обязательно. Если ты вызываешь нестатическую функцию-член класса через
указатель, то нужно передать указатель на класс.
VV>> network.SetParameter(SetGain, 0);
VV>> network.SetParameter(SetPhase, 1);
HZ> Хм, разве SetGain и SetPhase видны в этой области видимости?
Конечно.
VV>> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV>> подобный вызов. Можно ли это обойти?
HZ> Hе очень понятно, что там получается (вот если б на листинг со
HZ> сгенеренным кодом посмотреть),
Посмотрел. В RAM появляется статическая таблица указателей на вызываемые
функции-члены класса. Зачем - непонятно. Ведь это константные адреса.
VLV

IAR EC++ - как правильно?
Dear Vladimir,
09 Dec 03 21:39, Vladimir Vassilevsky wrote to Harry Zhurov:
VV> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV> после вызова нужно сделать одинаковую вспомогательную работу. Кроме того,
VV> cаму функцию-член надо вызывать в цикле несколько раз. Хочется завернуть
VV> все это хозяйство в одну универсальную функцию, которой передается
VV> указатель на член. Конечно, вместо этого можно просто сделать switch из
VV> явных вызовов посередине универсальной функции и передавать параметр для
VV> свича, однако так делать некузяво.
А можно отдельно описать ф-ции DoSomething() и DoSomethingElse(). Далее
вызывать твои ф-ции SetSomething() напрямую, из которых вызывать эти
стандартные прологи и эпилоги. Ф-цию SetParameter() удалить как лишнюю и
вредную.
Sincerely yours,
Old Greaser.
09 Dec 03 21:39, Vladimir Vassilevsky wrote to Harry Zhurov:
VV> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV> после вызова нужно сделать одинаковую вспомогательную работу. Кроме того,
VV> cаму функцию-член надо вызывать в цикле несколько раз. Хочется завернуть
VV> все это хозяйство в одну универсальную функцию, которой передается
VV> указатель на член. Конечно, вместо этого можно просто сделать switch из
VV> явных вызовов посередине универсальной функции и передавать параметр для
VV> свича, однако так делать некузяво.
А можно отдельно описать ф-ции DoSomething() и DoSomethingElse(). Далее
вызывать твои ф-ции SetSomething() напрямую, из которых вызывать эти
стандартные прологи и эпилоги. Ф-цию SetParameter() удалить как лишнюю и
вредную.
Sincerely yours,
Old Greaser.

IAR EC++ - как правильно?
Tue Dec 09 2003 23:12, Serge Bryxin wrote to Vladimir Vassilevsky:
VV>> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV>> после вызова нужно сделать одинаковую вспомогательную работу. Кроме
VV>> того, cаму функцию-член надо вызывать в цикле несколько раз. Хочется
VV>> завернуть все это хозяйство в одну универсальную функцию, которой
VV>> передается указатель на член. Конечно, вместо этого можно просто
VV>> сделать switch из явных вызовов посередине универсальной функции и
VV>> передавать параметр для свича, однако так делать некузяво.
SB> А можно отдельно описать ф-ции DoSomething() и DoSomethingElse(). Далее
SB> вызывать твои ф-ции SetSomething() напрямую, из которых вызывать эти
SB> стандартные прологи и эпилоги. Ф-цию SetParameter() удалить как лишнюю и
SB> вредную.
Функций SetSomething() несколько десятков. Они могут вызываться как
сами по себе, так и в составе примерно такой процедуры:
DoSomething();
for(ci = 0; ci < number; ci++) SetSomething(ci);
DoSomethingElse();
Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
но с циклом так не расправишься.
SB> Sincerely yours,
SB> Old Greaser.
VLV
VV>> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV>> после вызова нужно сделать одинаковую вспомогательную работу. Кроме
VV>> того, cаму функцию-член надо вызывать в цикле несколько раз. Хочется
VV>> завернуть все это хозяйство в одну универсальную функцию, которой
VV>> передается указатель на член. Конечно, вместо этого можно просто
VV>> сделать switch из явных вызовов посередине универсальной функции и
VV>> передавать параметр для свича, однако так делать некузяво.
SB> А можно отдельно описать ф-ции DoSomething() и DoSomethingElse(). Далее
SB> вызывать твои ф-ции SetSomething() напрямую, из которых вызывать эти
SB> стандартные прологи и эпилоги. Ф-цию SetParameter() удалить как лишнюю и
SB> вредную.
Функций SetSomething() несколько десятков. Они могут вызываться как
сами по себе, так и в составе примерно такой процедуры:
DoSomething();
for(ci = 0; ci < number; ci++) SetSomething(ci);
DoSomethingElse();
Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
но с циклом так не расправишься.
SB> Sincerely yours,
SB> Old Greaser.
VLV

IAR EC++ - как правильно?
Wed, 10 Dec 2003 22:35:01 +0300 Vladimir Vassilevsky wrote to Serge Bryxin:
[...]
VV> DoSomething();
VV> for(ci = 0; ci < number; ci++) SetSomething(ci);
VV> DoSomethingElse();
VV> Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
VV> но с циклом так не расправишься.
// --------------------------------------------
class TSlon
{
public:
TSlon() { DoSomething(); }
~TSlon() { DoSomethingElse(); }
};
void f()
{
... //
{ TSlon sl; for(ci = 0; ci < number; ci++) SetSomething(ci); }
... //
}
// --------------------------------------------
Меньше писанины, и не забудешь эпилог вызвать. Таким способом можно
оборачивать почти любые фрагменты кода. Если этих пар функций много, то
придется написать соответствующее количество врапперов.
[...]
VV> DoSomething();
VV> for(ci = 0; ci < number; ci++) SetSomething(ci);
VV> DoSomethingElse();
VV> Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
VV> но с циклом так не расправишься.
// --------------------------------------------
class TSlon
{
public:
TSlon() { DoSomething(); }
~TSlon() { DoSomethingElse(); }
};
void f()
{
... //
{ TSlon sl; for(ci = 0; ci < number; ci++) SetSomething(ci); }
... //
}
// --------------------------------------------
Меньше писанины, и не забудешь эпилог вызвать. Таким способом можно
оборачивать почти любые фрагменты кода. Если этих пар функций много, то
придется написать соответствующее количество врапперов.
--
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
We've slightly trimmed the long signature. Click to see the full one.

IAR EC++ - как правильно?
Dear Vladimir,
10 Dec 03 22:35, Vladimir Vassilevsky wrote to Serge Bryxin:
SB>> можно отдельно описать ф-ции DoSomething() и DoSomethingElse().
SB>> Далее вызывать твои ф-ции SetSomething() напрямую, из которых
SB>> вызывать эти стандартные прологи и эпилоги.
VV> Функций SetSomething() несколько десятков. Они могут вызываться как
VV> сами по себе, так и в составе примерно такой процедуры:
VV> DoSomething();
VV> for(ci = 0; ci < number; ci++) SetSomething(ci);
VV> DoSomethingElse();
VV> Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
VV> но с циклом так не расправишься.
Так и я, в общем-то, враппер предлагаю. А почему с циклом не расправиться?
Hапример:
SetSomething(int start, int number, bool init)
{ register int i;
if( init )
DoSomething();
for( i=start; i<start+number; i++ )
{ ActuallySet(i);
}
if( init )
DoSomethingElse();
}
Hа самом деле по-хорошему ф-цию ActuallySet() описывать не надо. В цикле -
собственно алгоритм установки ( i.e. тело твоей текущей SetSomething() ). Ибо
каждый лишний CALL в циклах - плохо в принципе.
Если скорость вызова ActuallySet() без пролога и эпилога смертельно критична,
можно таки ее описать (а параметр init опустить, возожно и параметр start
опустить, если цикл всегда от 0), но в общем случае я бы не стал.
До кучи:
#define SetSomething1(X) SetSomething((X),1,false)
Блин, насколько все это проще и изящнее на Асме! :-)
Флаг T взвел, CALL прямо на метку ActuallySet, BRTC дальше, иначе RET.
Sincerely yours,
Old Greaser.
10 Dec 03 22:35, Vladimir Vassilevsky wrote to Serge Bryxin:
SB>> можно отдельно описать ф-ции DoSomething() и DoSomethingElse().
SB>> Далее вызывать твои ф-ции SetSomething() напрямую, из которых
SB>> вызывать эти стандартные прологи и эпилоги.
VV> Функций SetSomething() несколько десятков. Они могут вызываться как
VV> сами по себе, так и в составе примерно такой процедуры:
VV> DoSomething();
VV> for(ci = 0; ci < number; ci++) SetSomething(ci);
VV> DoSomethingElse();
VV> Hачало и конец можно сделать в виде враппера, как предложил Harry Zurov,
VV> но с циклом так не расправишься.
Так и я, в общем-то, враппер предлагаю. А почему с циклом не расправиться?
Hапример:
SetSomething(int start, int number, bool init)
{ register int i;
if( init )
DoSomething();
for( i=start; i<start+number; i++ )
{ ActuallySet(i);
}
if( init )
DoSomethingElse();
}
Hа самом деле по-хорошему ф-цию ActuallySet() описывать не надо. В цикле -
собственно алгоритм установки ( i.e. тело твоей текущей SetSomething() ). Ибо
каждый лишний CALL в циклах - плохо в принципе.
Если скорость вызова ActuallySet() без пролога и эпилога смертельно критична,
можно таки ее описать (а параметр init опустить, возожно и параметр start
опустить, если цикл всегда от 0), но в общем случае я бы не стал.
До кучи:
#define SetSomething1(X) SetSomething((X),1,false)
Блин, насколько все это проще и изящнее на Асме! :-)
Флаг T взвел, CALL прямо на метку ActuallySet, BRTC дальше, иначе RET.
Sincerely yours,
Old Greaser.

IAR EC++ - как правильно?
Tue, 09 Dec 2003 21:39:50 +0300 Vladimir Vassilevsky wrote to Harry Zhurov:
VV>>> Хочется использовать указатель на функцию - член класса:
HZ>> Tакое желание должно быть оправдано - указатели на члены как правило
HZ>> более "толстые" (оверхедные) и работать с ними менее удобно, чем с
HZ>> простыми указателями.
VV> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV> послевызова нужно сделать одинаковую вспомогательную работу. Кроме того,
VV> cаму функцию-член надо вызывать в цикле несколько раз. Хочется
VV> завернуть все это хозяйство в одну универсальную функцию, которой
VV> передается указатель на член.
VV> Конечно, вместо этого можно просто сделать switch из явных вызовов
VV> посередине универсальной функции и передавать параметр для свича,
VV> однако так делать некузяво.
Да, со свитчем некузяво.
Соображения такие. Всякое такое, что требует одинаковых действий до и
действий после, бывает удобно завернуть в "обертку", т.е. написать
класс-враппер, где в конструкторе выполняются действия ДО, а в деструкторе -
действия ПОСЛЕ. При использовании нужно просто создать объект и работать с ним,
а ДО и ПОСЛЕ выполнится автоматически, путем неявного вызова конструктора и
деструктора. Например:
class TSlon
{
public:
TSlon() { DoSomthing(); }
void SetGain(u8);
...
~TSlon() { DoSomthingElse(); }
private:
...
}
void main()
{
...
TSlon slon;
slon.SetGain(0);
}
Еще один вариант - использовать виртуальные функции, там таблица указателей
размешается во флеши (специально проверял). При этом нужно каждый параметр
будет сделать отдельным классом, производным от одного базового. В этом случае,
однако, появляются накладные расходы по памяти - каждый класс будет содержать
два байта указателя vptr. Зато есть бОльшая гибкость - можно вызывать по одному
указателю разные функции.
Ну, и остается традиционный вариант с помощью обычных указателей. Если не
хочется выносить функции в глобальную область видимости, то можно их сделать
статическими и работать как с обычными. Этот вариант, имхо, наиболее близок к
твоей реализации. Тем более, что все равно приходится явно метать this.
В общем, тут тебе думать/выбирать.
[...]
VV>>> network.SetParameter(SetGain, 0);
VV>>> network.SetParameter(SetPhase, 1);
HZ>> Хм, разве SetGain и SetPhase видны в этой области видимости?
VV> Конечно.
Да нет, их область видимости ограничена классом NETWORK, поэтому в таком
виде компилятор выдает ошибку:
-------------------------------------------------
network.SetParameter(SetGain, 0);
^
"D:\slon\IAR\AVR\VLV\slon.cpp",33 Error[Pe020]: identifier "SetGain" is
undefined
-------------------------------------------------
Т.е. не видит он тут такого имени. Чтобы он увидел, нужно написать:
network.SetParameter(NETWORK::SetGain, 0);
VV>>> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV>>> подобный вызов. Можно ли это обойти?
HZ>> Hе очень понятно, что там получается (вот если б на листинг со
HZ>> сгенеренным кодом посмотреть),
VV> Посмотрел. В RAM появляется статическая таблица указателей на вызываемые
VV> функции-члены класса. Зачем - непонятно. Ведь это константные адреса.
Именно. Вот он и размещает эти адреса в сегменте const. Просто сегмент
const в AVR располагается в ОЗУ, с этим ничего не поделаешь - архитектура
такая. Вот если бы у него хватало ума размещать эту таблицу во флеш, то это
было бы, наверное, то, что тебе надо. Но пока он не такой "умный" (что в
перспективе может составить предмет беседы с иаровцами). Хотя не уверен, можно
ли это в принципе сделать - не помню, разрешается ли адресная арифметика с
указателями на члены совместно с обычными указателями. Если не разрешается, то
тогда принципиальных проблем разместить в флеш нет, а если разрешается, то тады
"ой", жить ему в ОЗУ.
VV>>> Хочется использовать указатель на функцию - член класса:
HZ>> Tакое желание должно быть оправдано - указатели на члены как правило
HZ>> более "толстые" (оверхедные) и работать с ними менее удобно, чем с
HZ>> простыми указателями.
VV> Ситуация: есть небольшие похожие функции-члены, но перед их вызовом и
VV> послевызова нужно сделать одинаковую вспомогательную работу. Кроме того,
VV> cаму функцию-член надо вызывать в цикле несколько раз. Хочется
VV> завернуть все это хозяйство в одну универсальную функцию, которой
VV> передается указатель на член.
VV> Конечно, вместо этого можно просто сделать switch из явных вызовов
VV> посередине универсальной функции и передавать параметр для свича,
VV> однако так делать некузяво.
Да, со свитчем некузяво.
Соображения такие. Всякое такое, что требует одинаковых действий до и
действий после, бывает удобно завернуть в "обертку", т.е. написать
класс-враппер, где в конструкторе выполняются действия ДО, а в деструкторе -
действия ПОСЛЕ. При использовании нужно просто создать объект и работать с ним,
а ДО и ПОСЛЕ выполнится автоматически, путем неявного вызова конструктора и
деструктора. Например:
class TSlon
{
public:
TSlon() { DoSomthing(); }
void SetGain(u8);
...
~TSlon() { DoSomthingElse(); }
private:
...
}
void main()
{
...
TSlon slon;
slon.SetGain(0);
}
Еще один вариант - использовать виртуальные функции, там таблица указателей
размешается во флеши (специально проверял). При этом нужно каждый параметр
будет сделать отдельным классом, производным от одного базового. В этом случае,
однако, появляются накладные расходы по памяти - каждый класс будет содержать
два байта указателя vptr. Зато есть бОльшая гибкость - можно вызывать по одному
указателю разные функции.
Ну, и остается традиционный вариант с помощью обычных указателей. Если не
хочется выносить функции в глобальную область видимости, то можно их сделать
статическими и работать как с обычными. Этот вариант, имхо, наиболее близок к
твоей реализации. Тем более, что все равно приходится явно метать this.
В общем, тут тебе думать/выбирать.
[...]
VV>>> network.SetParameter(SetGain, 0);
VV>>> network.SetParameter(SetPhase, 1);
HZ>> Хм, разве SetGain и SetPhase видны в этой области видимости?
VV> Конечно.
Да нет, их область видимости ограничена классом NETWORK, поэтому в таком
виде компилятор выдает ошибку:
-------------------------------------------------
network.SetParameter(SetGain, 0);
^
"D:\slon\IAR\AVR\VLV\slon.cpp",33 Error[Pe020]: identifier "SetGain" is
undefined
-------------------------------------------------
Т.е. не видит он тут такого имени. Чтобы он увидел, нужно написать:
network.SetParameter(NETWORK::SetGain, 0);
VV>>> Проблема в том, что IAR статически (!) расходует RAM (NEAR_Z) на каждый
VV>>> подобный вызов. Можно ли это обойти?
HZ>> Hе очень понятно, что там получается (вот если б на листинг со
HZ>> сгенеренным кодом посмотреть),
VV> Посмотрел. В RAM появляется статическая таблица указателей на вызываемые
VV> функции-члены класса. Зачем - непонятно. Ведь это константные адреса.
Именно. Вот он и размещает эти адреса в сегменте const. Просто сегмент
const в AVR располагается в ОЗУ, с этим ничего не поделаешь - архитектура
такая. Вот если бы у него хватало ума размещать эту таблицу во флеш, то это
было бы, наверное, то, что тебе надо. Но пока он не такой "умный" (что в
перспективе может составить предмет беседы с иаровцами). Хотя не уверен, можно
ли это в принципе сделать - не помню, разрешается ли адресная арифметика с
указателями на члены совместно с обычными указателями. Если не разрешается, то
тогда принципиальных проблем разместить в флеш нет, а если разрешается, то тады
"ой", жить ему в ОЗУ.
--
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
H.Z.
harry.zhurov<antispam::at>ngs<antispam::period>ru
We've slightly trimmed the long signature. Click to see the full one.
Site Timeline
- » Дюраль Д16-Т собственно корпус для MC изделия...
- — Next thread in » Microcontrollers (Russian)
-
- » датчики давления
- — Previous thread in » Microcontrollers (Russian)
-
- » По моему это гениально
- — Newest thread in » Microcontrollers (Russian)
-
- » Drut srebrny, albo grubo posrebrzony miedziany.
- — The site's Newest Thread. Posted in » Electronics (Polish)
-