LINUX.ORG.RU

__attribute__((weak, alias («smth»)) для class member в C++

 , ,


0

1

Захотелось мне странного: сделать __attribute__((weak, alias для статических членов класса.

Про то, что в alias надо добавлять mangled name - знаю.

Получилось что-то такое:

class m3core
{
    public:
        static void DefaultHendler (void);
        static void Reset_Handler (void) __attribute__((weak, alias ("_ZN6m3core14DefaultHendlerEv")));
}
Но эти символы не находит.
error: static void m3core::Reset_Handler()' aliased to undefined symbol '_ZN6m3core14DefaultHendlerEv'
И не позволяет их переопределять:
error:redefinition of 'static void m3core::Reset_Handler()'|
error:'static void m3core::Reset_Handler()' previously defined here|
ЧЯДНТ?



Последнее исправление: dekar (всего исправлений: 1)

Ответ на: комментарий от dekar

Собственно aliased to undefined symbol означает что если бы в этом же файле было определение DefaultHendler, то проблем не будет. Кто мешает добавить? Если это include, то weak добавлять только для файла реализации.

io ★★
()
Ответ на: комментарий от io

Написал

class m3core
{
public:
static void DefaultHendler (void){}
static void Reset_Handler (void) __attribute__((weak, alias («_ZN6m3core14DefaultHendlerEv»)));


Ничего не поменялось

dekar
() автор топика
Ответ на: комментарий от dekar

m3core.h:

class m3core
{
    public:
        static void DefaultHendler (void);
        static void Reset_Handler (void)
#ifdef m3_core_implement
 __attribute__((weak, alias ("_ZN6m3core14DefaultHendlerEv")));
#else
 ;
#endif
};

m3core.cc:

#define m3_core_implement

#include "m3core.h"

void m3core::DefaultHendler(void) {}

Ну и где-то м.б. объявлена или нет реализация Reset_Handler.

io ★★
()
Ответ на: комментарий от dekar

Однако weak в этом случае нормально срабатывает и в m3core.o все корректно! Т.е. повторной перекомпиляции данного модуля при добавлении файла с реализацией не потребуется! Это не удаление за счет перекомпиляции!!

io ★★
()
Ответ на: комментарий от io

Мне нужно собрать такой класс-хедер, чтобы в реализации осталось только описать те функции, которые нужны.

dekar
() автор топика
Ответ на: комментарий от dekar

Проблема в том, что для weak используются следующие ассемблерные конструкции:

	.weak	_ZN6m3core13Reset_HandlerEv
	.set	_ZN6m3core13Reset_HandlerEv,_ZN6m3core14DefaultHendlerEv

Т.е. его можно задать только в том файле где DefaultHendler определен. Т.ч. в header-е weak может стоять только условно.

io ★★
()
Ответ на: комментарий от io

делал так:

class m3core
{
public:
static void DefaultHendler (void){}
static void Reset_Handler (void) __attribute__((weak, alias («_ZN6m3core14DefaultHendlerEv»)));
Тут DefaultHendler определён. Разницы небыло.

dekar
() автор топика
Ответ на: комментарий от xeiph

Такми образом прав ли я, думая, что нельзя объявить класс таким образом, чтобы его методы либо имели реализацию, либо ссылались на реализацию по-умолчанию?

dekar
() автор топика
Ответ на: комментарий от dekar

Просто объявить нет, а реализовать да.

io ★★
()
Ответ на: комментарий от xeiph

не знаю. Я хочу сделать шаблонный проект для микроконтроллеров на C++11. И без C-like препроцессора.

dekar
() автор топика
Ответ на: комментарий от dekar

А простое наследование тут не подойдёт? Оверхэда вроде быть не должно.

//m3core.h
class m3core_base
{
    public:
        static void Reset_Handler (void)
        { /* default implementation */ }
};
//m3core.c
class m3core : public m3core_base
{
    public:
      //static void Reset_Handler (void)
      //{ /* uncomment to  redefine */ }
};
xeiph
()
Ответ на: комментарий от xeiph

А, я понял!

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

dekar
() автор топика
~> g++ -c symbol.cxx
~> g++ -c main.cxx
~> g++ main.o symbol.o -o test
~> ./test
DefaultHandler
~> g++ -c -DRESET main.cxx
~> g++ main.o symbol.o -o test
~> ./test
ResetHandler
~> cat symbol.cxx
#include <stdio.h>
#include "symbol.h"

void m3core::DefaultHandler(void)
{
	printf("%s\n", __func__);
}

void m3core::ResetHandler(void) __attribute__((weak, alias ("_ZN6m3core14DefaultHandlerEv")));
~> cat symbol.h 
#ifndef SYMBOL_H
#define SYMBOL_H

class m3core
{
public:
	static void DefaultHandler (void);
	static void ResetHandler (void);
};

#endif /* SYMBOL_H */
~> cat main.cxx
#include <stdio.h>
#include "symbol.h"

int main()
{
	m3core::ResetHandler();
}

#ifdef RESET
void m3core::ResetHandler(void)
{
	printf("%s\n", __func__);
}
#endif
AptGet ★★★
()
Ответ на: комментарий от AptGet

А в каком файле надо заполнять массив указателей на вектора? типа


void (ISR_Vector[])(void) =
{
  m3core::ResetHandler,
  m3core::.....
  ...
} 

dekar
() автор топика
Ответ на: комментарий от fish_ka

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

dekar
() автор топика
Ответ на: комментарий от dekar

Разве что в ассемблере это не будет столь странно выглядет

На C - это будет выглядеть вполне приятно - примерно так - http://pastebin.com/qHcPxzcY

anonymous
()
Ответ на: комментарий от anonymous

Все круто, только main() обычно вызывается из ResetHandler а не наоборот.

Это пример чтоб показать, что weak работает.

обычно

У вас в микроконтроллерах своя атмосфера.

AptGet ★★★
()
Ответ на: комментарий от dekar

А в каком файле надо заполнять массив указателей на вектора? типа

Странный вопрос, я ж не знаю как у вас там все устроено. Я вообще не думаю, что эти функции подходят как вектора, на вашей платформе в обработчике прерывания с регистрами никаких манипуляций производить не надо?

AptGet ★★★
()
Ответ на: комментарий от AptGet

С регистрами манипуляции производит железо на ARM.
Если я сделаю объявление оного массива в файле с __attribute__((weak, alias («_ZN6m3core14DefaultHandlerEv»)));, изменится ли его содержание при реимплементации оного вектора в другом файле?

dekar
() автор топика
Ответ на: комментарий от fish_ka

Ну да, дружбы в крестах по минимуму, а вот магии - дофига :-)

Дружба не нужна - мир крутится от ненависти. Дружными языками все дружно не пользуются.

Pavval ★★★★★
()
Ответ на: комментарий от fish_ka

Дружба есть, но её следует избегать, потому что она нарушает инкапсуляцию.

xeiph
()
Ответ на: комментарий от dekar

С регистрами манипуляции производит железо на ARM.

Ну, на ARM11 нельзя было просто так взять и сделать обработчиком С-функцию.

Если я сделаю объявление оного массива в файле с __attribute__((weak, alias («_ZN6m3core14DefaultHandlerEv»)));, изменится ли его содержание при реимплементации оного вектора в другом файле?

Да, должно сработать.

AptGet ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.