Size: a a a

2020 March 22

AZ

Aleksander Zholtkovskii in pro.cxx
нет пути (с)
источник

AZ

Aleksander Zholtkovskii in pro.cxx
Как тогда попроще получить смещение поля в структуре?
источник

АК

Александр Караев in pro.cxx
template <std::uintptr_t D>
class Reg {
 static DEV* dev() { return (DEV*)D; }
};
источник

FS

Flower Surgeon in pro.cxx
Aleksander Zholtkovskii
Как тогда попроще получить смещение поля в структуре?
offsetof?
источник

FS

Flower Surgeon in pro.cxx
или что?
источник

AZ

Aleksander Zholtkovskii in pro.cxx
Александр Караев
template <std::uintptr_t D>
class Reg {
 static DEV* dev() { return (DEV*)D; }
};
А если мне нужен статический метод, не хочу создавать экземпляр объекта?
источник

АК

Александр Караев in pro.cxx
Aleksander Zholtkovskii
А если мне нужен статический метод, не хочу создавать экземпляр объекта?
Обновил код
источник

AZ

Aleksander Zholtkovskii in pro.cxx
Вернусь домой, попробую варианты
источник

АК

Александр Караев in pro.cxx
Можно даже сделать так:

template <class T, std::uintptr_t P> 
class Ptr {
 static T* get() { return (T*)P; }
 T* operator->() { return get(); }
};


И передавать как тип. Или как не-тип, если добавить implicit конструктор и включить C++20..
источник

P

Pavel in pro.cxx
Да не будет работать хак с разыменованием указателя, который не сгенерен компилятором. Только самому смещения считать (в примере там и считать нечего, я уже писал выше:

constexpr auto reg1 = (volatile uint32_t*)DEV_BASE;
constexpr auto reg2 = reg1 +1;

Если структура сложнее - нужно использовать offsetof
источник

q

qb60 in pro.cxx
Aleksander Zholtkovskii
нет пути (с)
https://habr.com/ru/post/459642/

Это не читал? Может наведёт на мысли.
источник

AZ

Aleksander Zholtkovskii in pro.cxx
qb60
https://habr.com/ru/post/459642/

Это не читал? Может наведёт на мысли.
это надо весь хедер с описанием периферии заново написать. Оно конечно здорово должно получиться, но имхо, это тупиковый путь
источник

AZ

Aleksander Zholtkovskii in pro.cxx
так сработало. Правда придётся добавить ещё портянку шаблонного кода, чтобы потом не тошнило от изобилия offsetof :)
источник

AZ

Aleksander Zholtkovskii in pro.cxx
Александр Караев
Не умеет компилятор в такое, увы. Он не может гарантировать валидность адресов, переданных в шаблон, поэтому и не принимает их. Не скомпилируется даже код с template <DEV* d = (DEV*)0x123>
А почему не может гарантировать? В коде же явно написано.
В рантайме компилятор почему-то не напрягаясь заменяет обращение к регистру через DEV->REG в одну операцию, и адрес берёт тоже с одного раза (в результирующем коде  явна видна константа)
источник

АК

Александр Караев in pro.cxx
Aleksander Zholtkovskii
А почему не может гарантировать? В коде же явно написано.
В рантайме компилятор почему-то не напрягаясь заменяет обращение к регистру через DEV->REG в одну операцию, и адрес берёт тоже с одного раза (в результирующем коде  явна видна константа)
Во-первых, reinterpret_cast запрещен в контексте времени компиляции. Во-вторых, даже код
constexpr int a[10];
constexpr int* p = &a[50];


даст ошибку, так как компилятор знает, что по адресу p нет настоящего объекта.
Впрочем, в обосновании последнего могу ошибаться, но всё следует из отсутствия гарантий для компилятора во время компиляции
источник

AZ

Aleksander Zholtkovskii in pro.cxx
это весьма странно. В языке великое множество способов отстрелить ногу, а этот, полезный способ, запретили :(
источник

YH

Yuri Hudobin in pro.cxx
Aleksander Zholtkovskii
это весьма странно. В языке великое множество способов отстрелить ногу, а этот, полезный способ, запретили :(
Для атмеги пришлось макросы подтягивать:
... static void set() { _SFR_IO8(R) |= _BV(B); };
static bool read() { return _SFR_IO8(R-2) & _BV(B); } ...
using MyPinB7 = MyPin<PORTB_ID, PORTB7>;
источник

FS

Flower Surgeon in pro.cxx
reinterpret_cast — зло
источник

FS

Flower Surgeon in pro.cxx
юзайте void * и static_cast через него
источник

FS

Flower Surgeon in pro.cxx
если нужен generic raw pointer
источник