реклама на сайте
подробности

 
 
> тонкости constexpr
esaulenka
сообщение Apr 21 2017, 12:01
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Здравствуйте.
Возникла проблема после апгрейда gcc 4.8 на последнюю (6-ю) версию.

Есть у меня класс - драйвер таймера, в котором используемый таймер описан как
static constexpr TIM_TypeDef * const SYSTIMER = TIM6;
где TIM6 - стандартный дефайн ((TIM_TypeDef *) TIM6_BASE).

Раньше всё было хорошо, компилировалось-работало, а теперь поломалось:
начиная с какой-то версии gcc подкрутили, и в полном соответствии со стандартом reinterpret_cast стал неконстантным выражением.

Народ на стековерфлоу предлагает удалить constexpr.
Что-то мне эта идея не нравится - мне в основном надо просто прочитать значение этого таймера, и код этот раздувается вдвое.

Что б тут сделать?.. Обратно #define не хочу...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
esaulenka
сообщение Apr 24 2017, 08:26
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Прошу прощения за пятничный сумбур, очень уж домой хотелось :-)

Код
Building file: ../Drivers/AccelDrv.cpp
Invoking: Cross ARM C++ Compiler
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -flto
-Wuninitialized  -g -DSTM32F105xC -DSTM32F10X_CL -I /skipped/ -std=gnu++11 -fabi-version=0 -fno-exceptions -fno-rtti
-MMD -MP -MF"Drivers/AccelDrv.d" -MT"Drivers/AccelDrv.o" -c -o "Drivers/AccelDrv.o" "../Drivers/AccelDrv.cpp"

In file included from ../Drivers/AccelDrv.cpp:8:0:
../Drivers/AccelDrv.h:39:30: error: reinterpret_cast from integer to pointer
  static PeriphBit<(uintptr_t)&EXTI->IMR, EXTI_IMR_MR1> ExtiUnmaskIRQ;
                              ^~~~~~~~~~
../Drivers/AccelDrv.h:39:54: note: in template argument for type 'unsigned int'
  static PeriphBit<(uintptr_t)&EXTI->IMR, EXTI_IMR_MR1> ExtiUnmaskIRQ;


Версия стандарта не влияет. Уровень оптимизации (проверял -Os и -Og) не влияет.

Ещё более корявое решение
static PeriphBit<EXTI_BASE + offsetof(EXTI_TypeDef, IMR), EXTI_IMR_MR1> ExtiUnmaskIRQ;
работает.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 24 2017, 11:19
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(esaulenka @ Apr 24 2017, 13:26) *
static PeriphBit<(uintptr_t)&EXTI->IMR, EXTI_IMR_MR1> ExtiUnmaskIRQ;

Ну, тоже можно выкрутиться как-то так:
Код
static constexpr uintptr_t IMRAddr() { return (uintptr_t)&EXTI->IMR; }
static PeriphBit2<IMRAddr(), EXTI_IMR_MR1> ExtiUnmaskIRQ;

Но мне больше нравится
EXTI_BASE + offsetof(EXTI_TypeDef, IMR). Насколько я понял, они оставили себе какую-то лазейку и исхитрились сделать offsetof() constexpr. Надо этим пользоватьсяsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
klen
сообщение May 17 2017, 12:53
Сообщение #4


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(AHTOXA @ Apr 24 2017, 14:19) *
EXTI_BASE + offsetof(EXTI_TypeDef, IMR). Насколько я понял, они оставили себе какую-то лазейку и исхитрились сделать offsetof() constexpr. Надо этим пользоватьсяsm.gif

ах тыж эво оно как!!!
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
век живи учись дураком помрешь....
спасибо.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th April 2024 - 20:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01412 секунд с 7
ELECTRONIX ©2004-2016