Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Снова про const
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Aprox
Искал свою проблему в форуме, но не нашел решения. Проблема в следующем. Имеется готовый проект на С для IAR-430A, кристаллы ARM ST91х. Использую структуры, состоящие из данных-констант вида:
Код
typedef struct{
  const Tsome_type  some_data1;
  const Tsome_type  some_data2;
  // ...etc
} Tsome_info;

Затем в коде на С создаю эти структуры с уже конкретными константами в полях
Код
const Tsome_info info1={,,,,,};
const Tsome_info info2={,,,,,};
const Tsome_info info3={,,,,,};
//..etc

На С все прекрасно живет, компилятор помещает мои структуры в сегмент CONST, а линкер- в ROM. Но, тот же самый код на СPP приводит к размещению структур в сегменте CSTACK вместе с другими объектами. В результате куча констант хранится в RAM, которой и так мало! Я в шоке. wacko.gif Можно ли как-то победить эту проблему? Или придется перелопачивать идеологию проекта?


Сергей Борщ
QUOTE (Aprox @ Jan 10 2011, 11:05) *
На С все прекрасно живет, компилятор помещает мои структуры в сегмент CONST, а линкер- в ROM. Но, тот же самый код на СPP приводит к размещению структур в сегменте CSTACK вместе с другими объектами.
Странно это. Разница между C и C++ в плане const лишь в том, что в C++ константы по-умолчанию имеют локальную область видимости, что соответствует static const в C. Чтобы получить константы с глобальной областью видимости, их надо определять через extern const type = value; Но это никак не связано с размещением на стеке. Приведите побольше кода, попробуем разобраться.
sergeeff
Ну и оставьте свои

Код
const Tsome_info info1={,,,,,};
...


в С-ом модуле, а в .h файле объявите их как

Код
#ifdef __cplusplus

extern "C" const Tsome_info info1;

#else

extern const Tsome_info info1;

#endif


Aprox
Спасибо за идею! Действительно, проект можно составить из модулей, написанных и на С и на СРР. Чисто на CPP создавать структуры из данных-констант в ROM видимо не получится. В руководстве прочитал, что объекты и структуры компилятор СРР IAR размещает в сегмент CSTACK, который затем в RAM.

В принципе задача следующая. В проекте создается много объектов визуализации и редактирования разнородных переменных. Каждый объект имеет свое описание в виде набора неизменных свойств/параметров, этой визуализации.
Помещать эти свойства в виде данных в состав класса - неразумный расход RAM. Я решил поместить в класс только ссылку на структуру из свойств-констант. И вот тут-то меня ждал описанный выше облом- такую структуру нельзя создавать в теле кода на СPP. Выход найден. Но насколько он идейный? Как люди поступают в подобных случаях?


sergeeff
В общем случае надо явно компилятору/линкеру сообщить, какие данные в каком именно сегменте вы хотите расположить, а не просто использовать размещение по умолчанию. Синтаксис таких команд сильно зависит от применяемой связки компилятор/линкер. Почитайте документацию, это не очень сложно.
dimka76
А если IAR посвежее взять может там что-то изменили.
Сергей Борщ
QUOTE (Aprox @ Jan 10 2011, 12:55) *
Чисто на CPP создавать структуры из данных-констант в ROM видимо не получится. В руководстве прочитал, что объекты и структуры компилятор СРР IAR размещает в сегмент CSTACK, который затем в RAM.
Уже несколько лет пользуюсь ИАРом 4.30, пишу на C++, и он все константы прекрасно располагает во флеше:
CODE
     9          struct my_type
     10          {
     11              int a;
     12              int b;
     13          };
     14          

   \                                 In segment DATA_C, align 4, align-sorted
     15          extern my_type const aa = {1,2};
   \                     aa:
   \   00000000   010000000200       DC32 1, 2
   \              0000        

   \                                 In segment DATA_C, align 4, align-sorted
     16          extern my_type const bb = {3,4};
   \                     bb:
   \   00000000   030000000400       DC32 3, 4
   \              0000

А вы эти константы случайно не внутри функции без static объявляете?
Aprox
Цитата(sergeeff @ Jan 10 2011, 14:05) *
В общем случае надо явно компилятору/линкеру сообщить, какие данные в каком именно сегменте вы хотите расположить, а не просто использовать размещение по умолчанию. Синтаксис таких команд сильно зависит от применяемой связки компилятор/линкер. Почитайте документацию, это не очень сложно.
Понимаете, я хотел получить упрощение написания программ за счет перехода на обьектное программирование, а получается, надо разбираться в куче дополнительных подробностей, которые сводят на нет преимущества СРР. Понятно, что директивами pragma можно рулить сегментами. Но зачем эти сложности и лишний раз тыкать в клавиатуру? В кодах на "С" все нужное происходит автоматом.
Кроме того, я четко видел в мануале- объекты и структуры помещаются в один сегмент данных. И тут, наверное, уже никакими ухищрениями их не разъединить.


Цитата(Сергей Борщ @ Jan 10 2011, 14:58) *
Уже несколько лет пользуюсь ИАРом 4.30, пишу на C++, и он все константы прекрасно располагает во флеше:

Вот мой участок кода, который структуру из констант размещает в RAM. Тестовая программа в файле с расширением .cpp, т.е. будет работать СРР компилятор.
Код
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

typedef struct{
   const char* row[2];
} TFormInfo;


int main()
{
  const TFormInfo form_info ={
   "row1",
   "row2"
  };

  return 0;
}
Пробежав симулятором от main до return, открываем структуру в QuickWatch и видим- она размещена в RAM.
sergeeff
Вы должны четко понять, что С и С++ это разные компиляторы. Сам С++ существенно строже работает с разными типами данных и это сделано для повышения надежности и безопасности генерируемого кода.

В приведенном вами примере структура будет располагаться в стеке, так как объявлена внутри функции, соответственно в RAM. Коллега Борщ советовал вам ее объявить как:

Код
static const TFormInfo form_info ={
   "row1",
   "row2"
  };

Попробуйте!

Да, и кто вам сказал, что программа на С++ будет проще, чем на С? Там своих заморочек будет предостаточно, особенно на этапе его освоения.
Oldring
Цитата(Aprox @ Jan 10 2011, 12:05) *
Я в шоке.


В плюсах модификатор const не гарантирует, что объект не будет изменяться во время работы программы. Для программ обычных компов это не критично. Для встроенных систем изучайте тонкости настроек компилятора, с целью заставить его поместить объект в ROM.
Сергей Борщ
QUOTE (Aprox @ Jan 10 2011, 21:44) *
Вот мой участок кода, который структуру из констант размещает в RAM.
Никто не дает гарантии, что С-компилятор разместит эту структуру во флеше. Локальные автоматические переменные компилятор размещает в регистрах или на стеке. Квалификатор const запрещает обращение на запись к такой переменной, не более. И лишь объявление локальной переменной с квалификатором static делает такую переменную неавтоматической и позволяет разместить ее в сегменте DATA_C. Добавьте static к своей переменной и в С и С++ программе - переменная ляжет во флешь.
Aprox
Спасибо огромное! Действительно, попробовал поместить структуру констант в область глобальных переменных и она легла во флешь. Еще раз спасибо, что помогли распутать ситуацию. rolleyes.gif
Сергей Борщ
QUOTE (Aprox @ Jan 11 2011, 05:36) *
Действительно, попробовал поместить структуру констант в область глобальных переменных и она легла во флешь.
Хотя достаточно было сделать ее статической, оставив локальной. Хозяин - барин...
Aprox
Цитата(Сергей Борщ @ Jan 11 2011, 09:36) *
Хотя достаточно было сделать ее статической, оставив локальной. Хозяин - барин...
Да, спасибо. Я просто хотел сделать точно также, как раньше писал на С. Теперь вижу,- был неправ, разницы нет. Ваши советы навели на мысль, что в старом проекте на С декларации констант локально приводили к их размещению в RAM. Пойду сейчас проверять и исправлять.

dxp
Цитата(Oldring @ Jan 11 2011, 02:15) *
В плюсах модификатор const не гарантирует, что объект не будет изменяться во время работы программы.

Это как это? А что же тогда он гарантирует? И почему "в плюсах"? А в голом Цэ по-иному строится отношение к константным объектам?

Квалификатор const не гарантирует, что объект будет размещаться в ПЗУ (если оно вообще есть в наличие), это да. А насчет изменения очень даже гарантирует. И чтобы это обойти, придется использовать хаки (на свой страх и риск, ессно).
Oldring
Цитата(dxp @ Jan 11 2011, 14:53) *
Это как это? А что же тогда он гарантирует? И почему "в плюсах"? А в голом Цэ по-иному строится отношение к константным объектам?


В голых сях - иначе. Было у Страуструпа эссе по этому поводу.
Слово гарантирует, что программист не модифицирует объект неумышленно. Но всё равно если есть конструктор-деструктор, они будут вызваны. И иногда константные объекты мутируют. Было даже введено в язык специальное ключевое слово "mutable". Но иногда обходятся по-старинке и без него, снимая константность с указателя.
Aprox
А все-таки, посоветуйте новичку в "плюсах", как наиболее грамотно и экономно в смысле RAM строить объекты, которые используют предопределенные свойства в виде набора констант. Можно на хрестоматийном примере компонента ComboBox. Там используется куча свойств-констант. Отсюда вопрос- как в Embedded С++ сделать так, чтобы свойства-константы оказались в ROM, а конструктор TComboBox выглядел бы прилично?
sergeeff
Цитата(Aprox @ Jan 11 2011, 23:04) *
А все-таки, посоветуйте новичку в "плюсах", как наиболее грамотно и экономно в смысле RAM строить объекты, которые используют предопределенные свойства в виде набора констант. Можно на хрестоматийном примере компонента ComboBox. Там используется куча свойств-констант. Отсюда вопрос- как в Embedded С++ сделать так, чтобы свойства-константы оказались в ROM, а конструктор TComboBox выглядел бы прилично?


Куда же вас понесло с "христоматийным" TComboBox в embedded на LPC?
AHTOXA
Цитата(Aprox @ Jan 12 2011, 00:04) *
как в Embedded С++ сделать так, чтобы свойства-константы оказались в ROM, а конструктор TComboBox выглядел бы прилично?

Ну вы всё правильно делаете - константные структуры, и указатель на них в качестве параметра конструктора.

Если объектов немного, то можно шаблонами. Типа
Код
struct ComboProps1
{
    enum { width = 200 };
    enum { height = 500 };
    enum { some_bool_prop1 = false };
    ...
};

struct ComboProps2
{
    enum { width = 300 };
    enum { height = 200 };
    enum { some_bool_prop1 = true };
    ...
};

template<typename Props> class TComboBox
{
    enum { width = Props::width };
...
}

TComboBox<ComboProps1> Combo1;
TComboBox<ComboProps2> Combo2;
Oldring
Цитата(Aprox @ Jan 11 2011, 22:04) *
А все-таки, посоветуйте новичку в "плюсах", как наиболее грамотно и экономно в смысле RAM строить объекты, которые используют предопределенные свойства в виде набора констант. Можно на хрестоматийном примере компонента ComboBox. Там используется куча свойств-констант. Отсюда вопрос- как в Embedded С++ сделать так, чтобы свойства-константы оказались в ROM, а конструктор TComboBox выглядел бы прилично?



Объект не может одновременно находиться в ROM и в RAM. Поэтому, если у объекта есть изменяемые поля - он может находиться только в RAM. При этом декларативные свойства объекта могут быть описаны в виде структуры-агрегата, которая может располагаться в ROM. Объект при этом должен содержать указатель на эту константную структуру с этими неизменяемыми параметрами.
dxp
Цитата(Oldring @ Jan 11 2011, 18:25) *
В голых сях - иначе. Было у Страуструпа эссе по этому поводу.
Слово гарантирует, что программист не модифицирует объект неумышленно. Но всё равно если есть конструктор-деструктор, они будут вызваны.

Ни конструктор, ни деструктор не изменяют константных членов-данных. Только создают или удаляют. То, что это не очень вяжется с концепциями реализации ПЗУ - так ПЗУ и константы - это разные вещи. В конструкторе допускается инициализация константных полей, но только в списке инициализации, в теле конструктора уже нет. И работает это только для целых (почему такое ограничение, не знаю). Т.ч. ничего там не меняется.

Цитата(Oldring @ Jan 11 2011, 18:25) *
И иногда константные объекты мутируют. Было даже введено в язык специальное ключевое слово "mutable". Но иногда обходятся по-старинке и без него, снимая константность с указателя.

mutable - это из другой песни. Это нужно, чтобы можно было отдельные поля модифицировать в фукнциях-членах, объявленных как const. Заметьте, что речь идет не о константных членах-данных. Такие данные изменить не получится в любом случае.
Oldring
Цитата(dxp @ Jan 12 2011, 11:12) *
Такие данные изменить не получится в любом случае.


После явного снятия константности - легко.
jorikdima
Цитата(dxp @ Jan 12 2011, 11:12) *
Такие данные изменить не получится в любом случае.

const_cast<>() ?
ReAl
const_cast<> цяця-ляля, но до тех пор, пока мы снимаем то, что оделось по дроге - метка (*1) ниже.
А когда оно изначально было const -- метка (*2) -- имеем в полный рост UB, что как раз в embedded с флешами всякими и вылезет.
На PC шара прокатывает. Пока не начали секции с константами селить в страницы "только для чтения" с исключениями "генерал Фаульта" при попытке записи.

C++2003 7.1.5.1 The cv-qualifiers
...
4 Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.
5 [Example:
Код
const int ci = 3; // cv-qualified (initialized as required)
ci = 4;               // ill-formed: attempt to modify const
int i = 2;            // not cv-qualified
const int* cip;   // pointer to const int
cip = &i;            // OK: cv-qualified access path to unqualified
*cip = 4;            // ill-formed: attempt to modify through ptr to const
int* ip;               // cast needed to convert const int* to int*
ip = const_cast<int*>(cip); // defined: *ip points to i, a non-const object     (*1)
*ip = 4;
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq);    // cast required
*iq = 4;                            // undefined: modifies a const object      (*2)
dxp
Цитата(jorikdima @ Jan 12 2011, 18:34) *
const_cast<>() ?

После const_cast<> компилятор "умывает руки" и никакой защиты и проверок со его стороны стороны нет. Речь шла о безопасных преобразованиях (для чего умышленно вводят const в объявления) по правилам языка - так вот они не допускают модификации константных объектов.

Цитата(Oldring @ Jan 12 2011, 14:29) *
После явного снятия константности - легко.

Ага. А еще метод:

const int a = 10;

int addr = (int)&a;

int *p = (int*)addr;

(*p)++;

И еще много таких финтов можно придумать. Только речь о конструкциях языка, а не о хаках
Aprox
Цитата(AHTOXA @ Jan 12 2011, 00:52) *
Ну вы всё правильно делаете - константные структуры, и указатель на них в качестве параметра конструктора.
Ваш вариант задания констант-описаний выглядит читабельно и красиво. Однако, если в структуре-описания много разных типов, например, строки, указатели на места памяти, float и пр., то ваш вариант приводит к излишней писанине в момент декларации самих констант. Мне кажется, следующий вариант экономней в смысле писанины
Код
typedef struct{
   int i;
   float f;
   char* s;
} Tprops;

//----здесь декларации свойств с экономией писанины
static const Tprops prop1 ={13, 3.14, "Name1"}; // это точно попадает в ROM
static const Tprops prop2 ={16, 2.73, "Name2"}; // это точно попадает в ROM

class Tobj {//-------------
  const Tprops* p;
public:
  Tobj(){}
  Tobj(const Tprops* prop) {p=prop;}
  
// здесь можно пользоваться элементами описания *p.f или p->i
};

Tobj example1=&prop1;
Tobj example2=&prop2;

...

AHTOXA
Цитата(Aprox @ Jan 13 2011, 14:05) *
Мне кажется, следующий вариант экономней в смысле писанины

Дык, моя фраза
Цитата(AHTOXA @ Jan 12 2011, 02:52) *
константные структуры, и указатель на них в качестве параметра конструктора.

была как раз про этот вариант sm.gif А с шаблонами - это альтернативный.
Oldring
Цитата(ReAl @ Jan 12 2011, 23:23) *
А когда оно изначально было const -- метка (*2) -- имеем в полный рост UB, что как раз в embedded с флешами всякими и вылезет.


Вы же не считаете, что запихивание констант во флеш - это defined bihavior?
Всё, что обсуждается в этой теме, и есть UB.

Цитата(Aprox @ Jan 13 2011, 12:05) *
[code]typedef struct{
int i;
float f;
char* s;
} Tprops;
[code]


Тут typedef в плюсах не нужен.

Цитата(dxp @ Jan 13 2011, 08:47) *
Только речь о конструкциях языка, а не о хаках


И у вас "конструкции языка".
Aprox
Цитата(AHTOXA @ Jan 13 2011, 12:29) *
А с шаблонами - это альтернативный.
Я про шаблоны и говорю, что писанины больше при инициализации полей структуры-описания. В каждом конкретном определении структуры свойств придется набирать имена полей и все сопутствующее. Кроме того, шаблоны не поддерживает Embedded C++, а переходить на Extended C++ сразу утяжеляет проект ненужными фичами.

Я тут подумал, можно несколько повысить быстродействие, если передавать конструктору класса не указатель на структуру-описание, а ссылку на эту структуру. Заодно и в методах классах обращение к описаниям будет выглядеть приятнее.
Сергей Борщ
QUOTE (Aprox @ Jan 13 2011, 13:23) *
Я тут подумал, можно несколько повысить быстродействие, если передавать конструктору класса не указатель на структуру-описание, а ссылку на эту структуру.
За счет чего будет подъем быстродействия? Как вы представляете внутренюю реализацию ссылки кроме как через указатель?
AHTOXA
Цитата(Aprox @ Jan 13 2011, 16:23) *
Я про шаблоны и говорю, что писанины больше при инициализации полей структуры-описания. В каждом конкретном определении структуры свойств придется набирать имена полей и все сопутствующее.

Это понятно. Плюс к тому, вы получаете фактически по классу на каждый экземпляр объекта. Поэтому я и написал, "если объектов немного".
Но есть у шаблонов и плюсы. Например, все ветки if () и case, зависящие от константных параметров шаблона, компилятор вычислит на этапе компиляции (то есть их не останется).
То есть, код
Код
    if (some_bool_prop1)
        func1();
    else
        func2();
при some_bool_prop1 == true будет скомпилирован в
Код
    func1();




Цитата(Сергей Борщ @ Jan 13 2011, 16:36) *
За счет чего будет подъем быстродействия? Как вы представляете внутренюю реализацию ссылки кроме как через указатель?

Может, для ссылки на константу есть надежда, что компилятор подставит константу прямо в код?
Aprox
Цитата(AHTOXA @ Jan 13 2011, 21:40) *
Может, для ссылки на константу есть надежда, что компилятор подставит константу прямо в код?
Подскажите, какие существуют методы для проверки подобных гипотез? Дисассемблер?
AHTOXA
А как иначе? sm.gif
Ну или можно скомпилировать оба варианта и сравнить размеры получившихся программ.
Aprox
Цитата(AHTOXA @ Jan 14 2011, 11:39) *
А как иначе? sm.gif
Ну или можно скомпилировать оба варианта и сравнить размеры получившихся программ.
Попробовал. Дисассемблером не лазил, а размеры программ сравнил. Практически неотличимо.

Как передавать создаваемому объекту структуру из констант разобрался. Прошу дальнейшей помощи идейного плана. Сейчас уперся в другое. Задача стоит прорисовывать в окне разнородные объекты, например. TComboBox, TCheckBox. TRadioButton..etc., каждый имеет свое описание в виде структур констант, тоже разнотипных. Я думал создать базовый класс TObj с виртуальной функцией прорисовки и от него уже наследовать разнотипные классы, каждый со своей конкретной прорисовкой. Далее думал создать массив указателей на базовые объекты прорисовки и в цикле, по очереди вызывать функцию прорисовки базового объекта.
Тупик наступил на этапе- где должен размещаться указатель на структуру описание, в базовом, или наследуемом классе? По идее в наследуемом. Но тогда до нее не доберешься из базового класса, а ведь цикл прорисовки идет именно по списку из указателей на базовые. Если структуру-констант разместить в базовом классе, то теряется вся идея, поскольку структуры все разного типа и указать конкретно один тип, базовый, не представляется возможным. Прошу совета у гуру С++ - как быть? Также прошу иметь в виду, что речь идет об ARM кристаллах, в которых RAM - маловато, а ROM- много больше. Т.е. по-прежнему загвоздка с директивой const.
AHTOXA
Цитата(Aprox @ Jan 19 2011, 23:50) *
По идее в наследуемом. Но тогда до нее не доберешься из базового класса, а ведь цикл прорисовки идет именно по списку из указателей на базовые.

До неё и не надо добираться. Доступ к ней будет из функции Draw() наследуемого класса. А к функции Draw() доступ по указателю на базовый класс есть, так что всё в порядке.
Aprox
Цитата(AHTOXA @ Jan 19 2011, 22:44) *
До неё и не надо добираться. Доступ к ней будет из функции Draw() наследуемого класса. А к функции Draw() доступ по указателю на базовый класс есть, так что всё в порядке.
Спасибо, все получилось. rolleyes.gif
Aprox
И еще вдогонку вопрос. Как я понимаю, тот массив с указателями на обьекты окажется в RAM? Потому, что обьекты создаются на этапе исполнения программы, а не во время компиляции? У меня таких массивов довольно много, на С удавалось их поместить в ROM директивой const. А можно ли то же самое выполнить в С++ ? Чтобы списки обьектов помещались в ROM?

Сергей Борщ
QUOTE (Aprox @ Jan 20 2011, 08:46) *
Потому, что обьекты создаются на этапе исполнения программы, а не во время компиляции? У меня таких массивов довольно много, на С удавалось их поместить в ROM директивой const.
Как можно поместить в ROM адреса объектов, создаваемых на этапе исполнения? Ведь они создаются на стеке/в куче и их адрес заранее неизвестен. Если объекты глобальные, то можно сделать глобальный же массив указателей и его можно разместить в ROM.
Aprox
Цитата(Сергей Борщ @ Jan 20 2011, 10:51) *
Как можно поместить в ROM адреса объектов, создаваемых на этапе исполнения? Ведь они создаются на стеке/в куче и их адрес заранее неизвестен. Если объекты глобальные, то можно сделать глобальный же массив указателей и его можно разместить в ROM.
Да, разместить массив указателей можно в ROM, но использовать этот массив для вызова методов класса похоже нельзя. У меня лично не получается с IAR-ом. Вот простейший код:
Код
class Tobj {
public:
  Tobj(){}
  void Draw() {cout << "Hello"; }
};

Tobj obj;
static const Tobj *p= &obj;

int main()
{
  p->Draw();
  return 0;
}

При компиляции дает ошибку в операторе p->Draw();
Код
Error[Pe315]: the object has cv-qualifiers that are not compatible with the member function C:\AP\CPP\main.cpp
object type is: Tobj const __data
Что это значит, я затрудняюсь ответить.

Если же в означенном коде убрать static const при указателе на обьект, то все прекрасно живет, но указатель оказывается в RAM!
jorikdima
Цитата(Aprox @ Jan 21 2011, 10:49) *
Что это значит, я затрудняюсь ответить.

Если же в означенном коде убрать static const при указателе на обьект, то все прекрасно живет, но указатель оказывается в RAM!

Вот так надо:
Код
static Tobj const *p= &obj;

Прочитайте про квалификатор const у страуструпа или еще где. Он многогранен в зависимости от местоположения.
Указатель будет константным (то есть адрес на который он будет указывать известен на этапе компиляции), а вот объект obj может меняться.
Кстати можно и так:
Код
class Tobj {
public:
  Tobj(){}
  void Draw() const {cout << "Hello"; }
};

Tobj obj;
static Tobj const *p= &obj;

int main()
{
  p->Draw();
  return 0;
}
Aprox
Цитата(jorikdima @ Jan 21 2011, 11:10) *
Вот так надо:
Код
static Tobj const *p= &obj;

Прочитайте про квалификатор const у страуструпа или еще где. Он многогранен в зависимости от местоположения.
Указатель будет константным (то есть адрес на который он будет указывать известен на этапе компиляции), а вот объект obj может меняться.
Кстати можно и так:
Код
class Tobj {
public:
  Tobj(){}
  void Draw() const {cout << "Hello"; }
};

Tobj obj;
static Tobj const *p= &obj;

int main()
{
  p->Draw();
  return 0;
}

Попробовал ваш вариант. К сожалению, компилятор IAR хоть ошибок и не выдает, но упорно размещает константный указатель р в сегменте данных, т.е. в RAM кристалла. Проверял на симуляторе Embedded Workbench IAR ver.430A
Сергей Борщ
QUOTE (Aprox @ Jan 21 2011, 13:00) *
но упорно размещает константный указатель р в сегменте данных
Как называется сегмент, в который помещается указатель? Если DATA_C, то смотрите линкерный скрипт - перенесите этот сегмент из ОЗУ в ПЗУ.
Aprox
Цитата(Сергей Борщ @ Jan 21 2011, 14:09) *
Как называется сегмент, в который помещается указатель? Если DATA_C, то смотрите линкерный скрипт - перенесите этот сегмент из ОЗУ в ПЗУ.
Посмотрел. К сожалению, константный указатель попадает в сегмент DATA_I, т.е. в зону инициализируемых при стартапе переменных.
ReAl
Цитата(Aprox @ Jan 21 2011, 13:00) *
К сожалению, компилятор IAR хоть ошибок и не выдает, но упорно размещает константный указатель р в сегменте данных, т.е. в RAM кристалла.
Что-то я не нашёл тут константного указателя.
Код
const object_type *ptr;
object_type const *ptr;
суть изменяемые указатели на константные объекты. И там, и там *ptr имеет тип object_type с квалификатором const. А сам ptr квалификаторов не имеет.
Код
object_type * const ptr = &some_non_constant_object;
Константный указатель на изменяемый объект. Значение можно задать только при инициализации, потом указатель изменить нельзя.
Код
const object_type * const ptr = &some_constant_object;
Константный указатель на константный объект.
jorikdima
Цитата(ReAl @ Jan 21 2011, 16:59) *
Что-то я не нашёл тут константного указателя.
Код
const object_type *ptr;
object_type const *ptr;
суть изменяемые указатели на константные объекты. И там, и там *ptr имеет тип object_type с квалификатором const. А сам ptr квалификаторов не имеет.
Код
object_type * const ptr = &some_non_constant_object;
Константный указатель на изменяемый объект. Значение можно задать только при инициализации, потом указатель изменить нельзя.
Код
const object_type * const ptr = &some_constant_object;
Константный указатель на константный объект.

Бл***, вы правы, звездочку не справа от const, а слева надо ставить, чтоб константный указатель был. Сорри, описАлся sad.gif
Aprox
Цитата(ReAl @ Jan 21 2011, 16:59) *
Код
object_type * const ptr = &some_non_constant_object;
Константный указатель на изменяемый объект. Значение можно задать только при инициализации, потом указатель изменить нельзя.
Ура! Именно так и получилось загнать константный указатель в ROM. Спасибо! Теперь могу клепать проект на С++ для ST910
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.