|
Глюк ИАРа или мой?, Почему ИАР не дает проинициализировать статический атрибут класса |
|
|
|
 |
Ответов
|
May 16 2007, 07:05
|

Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 22-06-04
Из: Челябинск
Пользователь №: 88

|
Вот что получается... в мар файле Мои переменные лежат в коде сегменте Код 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 а в ассемблере берутся из ОЗУ.... Код internalVolt = initialUSLValue; \ 000000D8 .... LDI R30, LOW(??initialVoltValueRange) \ 000000DA .... LDI R31, (??initialVoltValueRange) >> 8 \ 000000DC 8100 LD R16, Z \ 000000DE 8111 LDD R17, Z+1 \ 000000E0 8122 LDD R18, Z+2 \ 000000E2 8133 LDD R19, Z+3 \ 000000E4 01FC MOVW R31:R30, R25:R24 \ 000000E6 5AE6 SUBI R30, 166 \ 000000E8 4FFF SBCI R31, 255 \ 000000EA 8300 ST Z, R16 \ 000000EC 8311 STD Z+1, R17 \ 000000EE 8322 STD Z+2, R18 \ 000000F0 8333 STD Z+3, R19 И что это ИАР сделал, то что я ему написал
|
|
|
|
|
May 16 2007, 16:54
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(lamerok @ May 16 2007, 14:05)  Вот что получается... в мар файле Мои переменные лежат в коде сегменте Код 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........ В выделенном Вами разделе речь идёт об интегральных (т. е. целых) и перечислимых типах, но никак не о плавающей точке.
|
|
|
|
|
May 17 2007, 00:57
|

Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 22-06-04
Из: Челябинск
Пользователь №: 88

|
Цитата(IgorKossak @ May 16 2007, 23:54)  NEAR_C это сегмент данных-констант, лежащий как раз там, где ему указано лежать линкером. А это может быть во внешней ПЗУ/ЕЕПРОМ/ФЛЕШ/и как ни странно ОЗУ. Проверьте настройки командного файла линкера. Хочу чтобы константы лежали во ФЛЕШЕ. Но компилятор сам расположил в КОДЕ сегменте(ФЛЕШЕ), а читает из ОЗУ.. непорядок... Согласен, я могу добиться, чтобы все было во флеше, поставив keyword __flash. Перед объявлением константных членов класса. И компилятор верно прочитает из ФЛЕШ. Код приводить не буду.. но читает из флеш по адресу статических констант членов класса. Могу добится чтобы они были в ОЗУ. Просто убрал в настройках компилятора --string_literals_in_flash и компилятор верно расположил все в ОЗУ и прочитал из ОЗУ. Но не пойму что мешает компилятору заменить все на просто число..???.Зачем нужно выделять под static const память, не важно где(в ОЗУ или флеше)...Для каких целей??? Ведь он позволяет сделать это для nonstatic constant (подставить число). (Что запрещено стандартом (проинициализировать их в декларации класса)) Цитата(IgorKossak @ May 16 2007, 23:54)  В любом случае доступ к ней как к памяти данных, а не программы, потому и через Z. В выделенном Вами разделе речь идёт об интегральных (т. е. целых) и перечислимых типах, но никак не о плавающей точке. Это многое объясняет... Все верно... получается флоат нельзя инициализировать в объявление класса. Спасибо, в споре рождается истина.
|
|
|
|
|
May 17 2007, 03:05
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(lamerok @ May 17 2007, 07:57)  Но компилятор сам расположил в КОДЕ сегменте(ФЛЕШЕ), а читает из ОЗУ.. непорядок... "Вася, ты зачем сломал игрушку?" "А оно САМО" Компилятор САМ ничего не делает. Он лишь тупо выполняет то, о чем вы его попросили. Дискуссия действительно плодотворная - про инициализацию статических константных членов прямо в описании класса я не знал, а теперь еще и понял ее механизм. Цитата(lamerok @ May 17 2007, 07:57)  Ведь он позволяет сделать это для nonstatic constant (подставить число). (Что запрещено стандартом (проинициализировать их в декларации класса)) Ну хорошо, попробуйте найти разницу в двух словосочетаниях: "nonstatic constant" и "nonstatic constant member". Nonstatic constant никакого отношения к классам не имеет, в отличие от nonstatic constatnt member. Что ж вы все никак не поймете, что если вы завели в классе нестатический член, то размер класа должен (обязан) увеличиться на размер этого члена (плюс выравнивание), даже если этот член read-only (константный). И лишь только если член статический, то он существует один на все объекты этого класса и поэтому память под него выделяется отдельно в количестве один штука на все объекты этого класса. И если этот статический член - константа, то вы можете ее проинициализировать в объявлении класса. Это гарантирует, что во всех .cpp, в которые вы включите определение этого класса константа будет иметь одно и то же значение. Из этого же следует, что значение этого статического константного члена известно компилятору в момент компиляции каждой единицы компиляции и этот факт дает возможность компилятору (но не обязывает) подставить куда надо значение этого члена не резервируя память. Или же вы только объявляете статический константный член в объявлении класса а определяете и инициализируете его где-то в другом месте (.cpp) и тогда компилятор безусловно выделит под него память, но внутри этого файла с момента когда значение константы ему известно может использовать значение инициализирующей константы не читая перемеенную. А инициализировать статический константный член разными значениями в разных единицах компиляции нельзя, потому что разные функции класса могут находиться в разных единицах компиляции но все должны работать с одинаковым (вплоть до значения констант) объектом.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 17 2007, 05:19
|

Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 22-06-04
Из: Челябинск
Пользователь №: 88

|
Цитата(Сергей Борщ @ May 17 2007, 10:05)  Что ж вы все никак не поймете, что если вы завели в классе нестатический член, то размер класа должен (обязан) увеличиться на размер этого члена (плюс выравнивание), даже если этот член 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; }; Размер класса одинаковый в обоих случаях. Цитата(Сергей Борщ @ May 17 2007, 10:05)  И лишь только если член статический, то он существует один на все объекты этого класса и поэтому память под него выделяется отдельно в количестве один штука на все объекты этого класса. И если этот статический член - константа, то вы можете ее проинициализировать в объявлении класса. Согласен, но только, если статический член - константа не floating point. Что выяснилось сегодня  (Спасибо IgorKossak) Цитата(Сергей Борщ @ May 17 2007, 10:05)  Это гарантирует, что во всех .cpp, в которые вы включите определение этого класса константа будет иметь одно и то же значение. Из этого же следует, что значение этого статического константного члена известно компилятору в момент компиляции каждой единицы компиляции и этот факт дает возможность компилятору (но не обязывает) подставить куда надо значение этого члена не резервируя память. Или же вы только объявляете статический константный член в объявлении класса а определяете и инициализируете его где-то в другом месте (.cpp) и тогда компилятор безусловно выделит под него память, но внутри этого файла с момента когда значение константы ему известно может использовать значение инициализирующей константы не читая перемеенную. Хммм... Почти согласен ... проведу еще пару экперементов.... подумаю... Цитата(Сергей Борщ @ May 17 2007, 10:05)  А инициализировать статический константный член разными значениями в разных единицах компиляции нельзя, потому что разные функции класса могут находиться в разных единицах компиляции но все должны работать с одинаковым (вплоть до значения констант) объектом. Согласен, компилятор просто не позволяет этого сделать. Пишет что он уже проинициализирован. Цитата(IgorKossak @ May 17 2007, 12:13)  Ещё раз повторяю, NEAR_C расположен не в КОДЕ сегменте, а в DATA сегменте. Как это обычно заявлено в командном файле Ну специально задал Код -Z(CODE)NEAR_C=_..X_INTVEC_SIZE-_..X_FLASH_END Чтобы все константы сувались в CODE
|
|
|
|
|
May 17 2007, 06:13
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(lamerok @ May 17 2007, 12:19)  Код -Z(CODE)NEAR_C=_..X_INTVEC_SIZE-_..X_FLASH_END Чтобы все константы сувались в CODE А теперь вспомните, в каком порядке происходит построение программы: сначала компилятор компилирует файл, и для обращения ко всем переменным без квалификатора __flash использует команды доступа в ОЗУ (LD, LDS, ST, STS). Именно квалификатором __flash вы указываете ему, что переменная(  ) будет лежать во флеш и ее нужно читать через LPM. Потом объектные файлы линкер "склеивает" в один большой проставляя желаемые вами адреса. А если вы компилятору сказали одно, линкеру-другое, то кто после этого вам злобный Буратина?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 20 2007, 16:03
|

Частый гость
 
Группа: Свой
Сообщений: 135
Регистрация: 22-06-04
Из: Челябинск
Пользователь №: 88

|
Цитата(Сергей Борщ @ May 17 2007, 09:13)  А теперь вспомните, в каком порядке происходит построение программы: сначала компилятор компилирует файл, и для обращения ко всем переменным без квалификатора __flash использует команды доступа в ОЗУ (LD, LDS, ST, STS). Именно квалификатором __flash вы указываете ему, что переменная(  ) будет лежать во флеш и ее нужно читать через LPM. Проверил на 4.21А - Правда ваша. На 4.12А, о чудо - работает так как я хочу... т.е. подставка числа, не резервирует память под static const член класса. В map файле ни слова про них (initialVoltValueRange и т.д.).
|
|
|
|
Сообщений в этой теме
lamerok Глюк ИАРа или мой? May 14 2007, 06:44 Сергей Борщ Цитата(lamerok @ May 14 2007, 09:44) Посм... May 14 2007, 12:00 IgorKossak Статические члены класса определяются и инициализи... May 14 2007, 15:26 lamerok Цитата(Сергей Борщ @ May 14 2007, 15:00) ... May 15 2007, 02:31 dxp Цитата(lamerok @ May 15 2007, 09:31) Т.е.... May 15 2007, 03:15  lamerok Цитата(dxp @ May 15 2007, 06:15) А с чего... May 15 2007, 03:43   Сергей Борщ Цитата(lamerok @ May 15 2007, 06:43) Но т... May 15 2007, 10:27    IgorKossak Цитата(Сергей Борщ @ May 15 2007, 17:27) ... May 15 2007, 15:51     zltigo Цитата(IgorKossak @ May 15 2007, 22:51) Э... May 15 2007, 16:32    lamerok Цитата(Сергей Борщ @ May 15 2007, 17:27) ... May 16 2007, 00:11     Сергей Борщ Цитата(lamerok @ May 16 2007, 07:11) Каже... May 16 2007, 04:31 lamerok Цитата(Сергей Борщ @ May 16 2007, 11:31) ... May 16 2007, 05:23 Сергей Борщ Цитата(lamerok @ May 16 2007, 12:23) Поче... May 16 2007, 06:59  lamerok Цитата(Сергей Борщ @ May 16 2007, 13:59) ... May 16 2007, 08:23   IgorKossak Цитата(lamerok @ May 17 2007, 07:57) Хочу... May 17 2007, 05:13 lamerok После кучи экспериментов пришел к выводу:
1. Можно... May 21 2007, 14:24
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|