Перейти к содержанию
    

Вот что получается... в мар файле Мои переменные лежат в коде сегменте

NEAR_C
  Relative segment, address: CODE 00000406 - 00000411 (0xc bytes), align: 0
  Segment part 9.             Intra module refs:   cClassDirector::cClassDirector()
           ENTRY                   ADDRESS         REF BY
           =====                   =======         ======
           cClassDirector::initialVoltValueRange
                                   0000040A 
           cClassDirector::initialCurValueRange
                                   0000040E 
           cClassDirector::initialTestValue
                                   00000406

 

а в ассемблере берутся из ОЗУ....

...

И что это ИАР сделал, то что я ему написал:)

NEAR_C это сегмент данных-констант, лежащий как раз там, где ему указано лежать линкером. А это может быть во внешней ПЗУ/ЕЕПРОМ/ФЛЕШ/и как ни странно ОЗУ. Проверьте настройки командного файла линкера.

В любом случае доступ к ней как к памяти данных, а не программы, потому и через Z.

 

(Сергей Борщ @ May 16 2007, 13:59)

 

Такое в С++ делать можно. Раз вы этого не знаете - последуйте своему совету:

 

См картинку раздел 4........

В выделенном Вами разделе речь идёт об интегральных (т. е. целых) и перечислимых типах, но никак не о плавающей точке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

NEAR_C это сегмент данных-констант, лежащий как раз там, где ему указано лежать линкером. А это может быть во внешней ПЗУ/ЕЕПРОМ/ФЛЕШ/и как ни странно ОЗУ. Проверьте настройки командного файла линкера.

Хочу чтобы константы лежали во ФЛЕШЕ. Но компилятор сам расположил в КОДЕ сегменте(ФЛЕШЕ), а читает из ОЗУ.. непорядок...

Согласен, я могу добиться, чтобы все было во флеше, поставив keyword __flash. Перед объявлением константных членов класса. И компилятор верно прочитает из ФЛЕШ. Код приводить не буду.. но читает из флеш по адресу статических констант членов класса.

 

Могу добится чтобы они были в ОЗУ. Просто убрал в настройках компилятора --string_literals_in_flash и компилятор верно расположил все в ОЗУ и прочитал из ОЗУ.

Но не пойму что мешает компилятору заменить все на просто число..???.Зачем нужно выделять под static const память, не важно где(в ОЗУ или флеше)...Для каких целей???

Ведь он позволяет сделать это для nonstatic constant (подставить число). (Что запрещено стандартом (проинициализировать их в декларации класса))

 

В любом случае доступ к ней как к памяти данных, а не программы, потому и через Z.

В выделенном Вами разделе речь идёт об интегральных (т. е. целых) и перечислимых типах, но никак не о плавающей точке.

Это многое объясняет... Все верно... получается флоат нельзя инициализировать в объявление класса.

Спасибо, в споре рождается истина.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но компилятор сам расположил в КОДЕ сегменте(ФЛЕШЕ), а читает из ОЗУ.. непорядок...
"Вася, ты зачем сломал игрушку?" "А оно САМО"

Компилятор САМ ничего не делает. Он лишь тупо выполняет то, о чем вы его попросили.

 

Дискуссия действительно плодотворная - про инициализацию статических константных членов прямо в описании класса я не знал, а теперь еще и понял ее механизм.

Ведь он позволяет сделать это для nonstatic constant (подставить число). (Что запрещено стандартом (проинициализировать их в декларации класса))
Ну хорошо, попробуйте найти разницу в двух словосочетаниях: "nonstatic constant" и "nonstatic constant member". Nonstatic constant никакого отношения к классам не имеет, в отличие от nonstatic constatnt member. Что ж вы все никак не поймете, что если вы завели в классе нестатический член, то размер класа должен (обязан) увеличиться на размер этого члена (плюс выравнивание), даже если этот член read-only (константный).

И лишь только если член статический, то он существует один на все объекты этого класса и поэтому память под него выделяется отдельно в количестве один штука на все объекты этого класса. И если этот статический член - константа, то вы можете ее проинициализировать в объявлении класса. Это гарантирует, что во всех .cpp, в которые вы включите определение этого класса константа будет иметь одно и то же значение. Из этого же следует, что значение этого статического константного члена известно компилятору в момент компиляции каждой единицы компиляции и этот факт дает возможность компилятору (но не обязывает) подставить куда надо значение этого члена не резервируя память. Или же вы только объявляете статический константный член в объявлении класса а определяете и инициализируете его где-то в другом месте (.cpp) и тогда компилятор безусловно выделит под него память, но внутри этого файла с момента когда значение константы ему известно может использовать значение инициализирующей константы не читая перемеенную.

А инициализировать статический константный член разными значениями в разных единицах компиляции нельзя, потому что разные функции класса могут находиться в разных единицах компиляции но все должны работать с одинаковым (вплоть до значения констант) объектом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хочу чтобы константы лежали во ФЛЕШЕ. Но компилятор сам расположил в КОДЕ сегменте(ФЛЕШЕ), а читает из ОЗУ.. непорядок...

Ещё раз повторяю, NEAR_C расположен не в КОДЕ сегменте, а в DATA сегменте. Как это обычно заявлено в командном файле

-Z(DATA)NEAR_C=_EXT_EPROM_BASE:+_EXT_EPROM_SIZE

Это пространство ДАННЫХ и если границы этого сегмента перекрываются с ОЗУ, то и будет он лежать в ОЗУ и константы будут браться оттуда. Примените квалификатор __flash и будет всё во flash, а непосредственно подставить плавающую константу согласно стандарта (Вами же приведённого) нельзя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что ж вы все никак не поймете, что если вы завели в классе нестатический член, то размер класа должен (обязан) увеличиться на размер этого члена (плюс выравнивание), даже если этот член read-only (константный).

Дак как раз это я почти пойму..... Компилятор (IAR 4.21A)этого не поймет. Побробуйте скомпилить вот это... и проверить размер класса сClassDirector

// Class.h
class cClass
{
     public:
      float getInternalVoltRange(void) const { return internalVoltRange; }
      float getInternalCurRange(void) const { return internalCurRange; }
      float getInternalTest(void) const { return internalTest; }

   private:
      float internalVoltRange;
      float internalCurRange;
      float internalTest;


      const float initialVoltValueRange  = 800.0f;  // Что за вата??? Почему так можно вообще делать???
      const float initialCurValueRange  = 0.40f;   
      const float initialTestValue  = 0.0f;
};

 

а потом вот это

// ClassDirtector.h
class cClassDirector
{
   public:
      float getInternalVoltRange(void) const { return internalVoltRange; }
      float getInternalCurRange(void) const { return internalCurRange; }
      float getInternalTest(void) const { return internalTest; }

   private:
      float internalVoltRange;
      float internalCurRange;
      float internalTest;


     static const float initialVoltValueRange;
     static const float initialCurValueRange;   
     static const float initialTestValue;
};

 

Размер класса одинаковый в обоих случаях.

И лишь только если член статический, то он существует один на все объекты этого класса и поэтому память под него выделяется отдельно в количестве один штука на все объекты этого класса. И если этот статический член - константа, то вы можете ее проинициализировать в объявлении класса.

Согласен, но только, если статический член - константа не floating point. Что выяснилось сегодня :) (Спасибо IgorKossak)

 

Это гарантирует, что во всех .cpp, в которые вы включите определение этого класса константа будет иметь одно и то же значение. Из этого же следует, что значение этого статического константного члена известно компилятору в момент компиляции каждой единицы компиляции и этот факт дает возможность компилятору (но не обязывает) подставить куда надо значение этого члена не резервируя память. Или же вы только объявляете статический константный член в объявлении класса а определяете и инициализируете его где-то в другом месте (.cpp) и тогда компилятор безусловно выделит под него память, но внутри этого файла с момента когда значение константы ему известно может использовать значение инициализирующей константы не читая перемеенную.

Хммм... Почти согласен ... проведу еще пару экперементов.... подумаю...

 

А инициализировать статический константный член разными значениями в разных единицах компиляции нельзя, потому что разные функции класса могут находиться в разных единицах компиляции но все должны работать с одинаковым (вплоть до значения констант) объектом.

Согласен, компилятор просто не позволяет этого сделать. Пишет что он уже проинициализирован.

 

 

Ещё раз повторяю, NEAR_C расположен не в КОДЕ сегменте, а в DATA сегменте. Как это обычно заявлено в командном файле

Ну специально задал

-Z(CODE)NEAR_C=_..X_INTVEC_SIZE-_..X_FLASH_END

Чтобы все константы сувались в CODE

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

-Z(CODE)NEAR_C=_..X_INTVEC_SIZE-_..X_FLASH_END

Чтобы все константы сувались в CODE

А теперь вспомните, в каком порядке происходит построение программы: сначала компилятор компилирует файл, и для обращения ко всем переменным без квалификатора __flash использует команды доступа в ОЗУ (LD, LDS, ST, STS). Именно квалификатором __flash вы указываете ему, что переменная( :) ) будет лежать во флеш и ее нужно читать через LPM. Потом объектные файлы линкер "склеивает" в один большой проставляя желаемые вами адреса. А если вы компилятору сказали одно, линкеру-другое, то кто после этого вам злобный Буратина? ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А теперь вспомните, в каком порядке происходит построение программы: сначала компилятор компилирует файл, и для обращения ко всем переменным без квалификатора __flash использует команды доступа в ОЗУ (LD, LDS, ST, STS). Именно квалификатором __flash вы указываете ему, что переменная( :) ) будет лежать во флеш и ее нужно читать через LPM.

 

Проверил на 4.21А - Правда ваша.

На 4.12А, о чудо - работает так как я хочу... т.е. подставка числа, не резервирует память под static const член класса. В map файле ни слова про них (initialVoltValueRange и т.д.).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После кучи экспериментов пришел к выводу:

1. Можно получить код с подстановкой непосредственно числа

2. Но трудно так как:

а) Обращение к static const члену должно быть в одном *.cpp файле

б) Зависит от кода.... Т.е., например, я обращаюсь к static const члену в конструкторе, в теле конструктора, перед обращение, куча условий. Если эти условия заремить или часть из них, или изменить порядок, то компилятор подставляет число, иначе Подставляется адрес static const члена.

в) Если обращаться к static const члену в двух и более *.cpp файлах, то в том файле в котором прошла инициализация члена идет подстановка числа в зависимоти от пункта б), в других тупое чтение с адреса члена.

3. Компилятор всегда располагает static const член в одном из сегментов памяти, либо NEAR_I, либо NEAR_C в зависимости от настроек компилятора.

4. Линкер, если не видит, что компилятор где то еще(кроме как в объявлении) использует ссылку на этот член, не резервируте под него память.

5. Если NEAR_C находится в сегменте CODE, то компилятор об этом не знает и читает с ОЗУ (как была сказано Сергеем)

6 Так лучше не делать :) Можно тупо воспользоваться #define, либо как было сказано, использовать __flash (но тогда будет команда чтения из флеша).

Спасибо всем за помощь.

Да все это касательно floating point.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...