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

уникальный идентификатор

собственно, вместо многократного повторения __attribute__ ((naked, section(".init7"))) для разных функций типа void foo(void) в разных файлах хочу сделать какой-то макрос, который сам бы это дело дописал перед каким-то автоматически сгенерированным идентификатором. в общем, пишем:

initialize{тут код начальной инициализации}

а получаем фактически что-то типа

__attribute__ ((naked, section(".init7"))) void _name120097553(void){nen код начальной инициализации}

 

подскажите, как сделать? ничего путнего не получается... проблема в формировании уникального идентификатора....

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


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

подскажите, как сделать?

 

Если в файле по одному иниту, их можно обозвать одинаково. :)

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


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

Если в файле по одному иниту, их можно обозвать одинаково. :)

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

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


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

Попробуйте для создания уникальных имен использовать макросы __LINE__ и __FILE__

так вот же ж :( их и пробовал... проблема в том, что как __LINE__ сконкатировать с символом? если я пишу так:

#define initialize void init ## __LINE__ (void)

то вместо ожидаемого

void init_234(void)

я получаю

void init___LINE__(void)

что неприемлемо...

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


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

Нужен еще один проход препроцессора.

Вот как раз Ваш случай:

http://electronix.ru/forum/index.php?s=&am...st&p=361393

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


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

так вот же ж :( их и пробовал... проблема в том, что как __LINE__ сконкатировать с символом? если я пишу так:

#define initialize void init ## __LINE__ (void)

то вместо ожидаемого

void init_234(void)

я получаю

void init___LINE__(void)

что неприемлемо...

поколдуйте с двойным переопределением.

например

#define MY_LINE __LINE__
#define MY_LINE2 MY_LINE

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


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

Нужен еще один проход препроцессора.

Вот как раз Ваш случай:

http://electronix.ru/forum/index.php?s=&am...st&p=361393

да, случай как раз мой. но почему-то когда я вручную писал static для инициализирующей функции, она исключалась уборщиком мусора (-Wl,-gc-sections -ffunction-sections)... наверное потому, что не было атрибута used?

спасибо за помощь!

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


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

она исключалась уборщиком мусора (-Wl,-gc-sections -ffunction-sections)... наверное потому, что не было атрибута used?
Да, именно поэтому.

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


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

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

Если так, то Вы ребята далеко ушли от программирования на С. Что неужели трудно явно вызывать процедуру инициализации? А как быть с расстановкой очерёдности инициализации разных модулей? С простотой портирования? С наглядностью наконец? На мой взгляд происходит подмена понятия программирования. Извините, но хочется понять глубинный смысл сего явления. Ответ типа: мне удобно т.к. я догадался до такого "извращения" - не то, что хочется услышать:) Я сторонник глубинного понимания языка программирования, а не фишек линкера и прочего инструментария, входящего в комплект поставки компилятора. Да это знать и понимать тоже нужно, но использовать так... Уж если считаете, что Вам стал жать С используйте С++ с его конструкторами и деструкторами, шаблонами и всем-всем остальным что Вам будет нужно. Так будет честнее. ИМХО.

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


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

А для чего, простите, весь сыр-бор. Чтобы лишь автоматизировать инициализацию какого-либо программного модуля?
Нет, периферии.
Если так, то Вы ребята далеко ушли от программирования на С. Что неужели трудно явно вызывать процедуру инициализации?
Трудно. На каждый вызов положить по ®call/ret и сохранение/восстановление контекста? Нафига? Если для этого есть специально разарботанный очень элегантный механизм.

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


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

Нет, периферии. ... Нафига? Если для этого есть специально разарботанный очень элегантный механизм.
Я вас прекрасно понимаю с точки зрения экономии ПЗУ, слабо с точки зрения повышения быстродействия. И совсем никак с моей личной точки зрения. Поясню. У меня обычно пользователю доступны режимы работы устройства (пусть это будет пресловутый UART), так после изменения настроек нужно вызвать процедуру инициализации повторно. Так если эта процедура у меня уже физически есть, то зачем мне всё это? Да есть такая периферия которая не отдаётся на откуп юзеру, так с ней можно и через static inline или __attribute__((always_inline)) "бороться". Хотя тут уже не принципиально как. Спасибо за ответ. Для меня тема исчерпана. Ваш метод имеет право на жизнь:)

2 ARV: гляньте, тут тоже происходит формирование уникальных идентификаторов:

#ifdef __cplusplus
    template<bool> struct CompileTimeError;
    template<> struct CompileTimeError<true> {};
#    define STATIC_ASSERT(expr)    (CompileTimeError<(expr) != 0>())
#else
#    define MY_JOIN_3_H(A,B,C)     A##B##C
#    define MY_JOIN_3(A,B,C)       MY_JOIN_3_H(A,B,C)
#    define STATIC_ASSERT_H(expr)  typedef int MY_JOIN_3(static_assert_,__LINE__,_h) [(expr) ? 1 : -1]
#    define STATIC_ASSERT(expr)    STATIC_ASSERT_H(expr)
#endif

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


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

2 demiurg_spb: спасибо, уже не надо, тем более, что принцип тот же самый, что и ранее, и даже тот же, о котором я сам думал... я лишь не сразу понял, что надо неоднократно макросы вкладывать друг в друга :)

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


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

Да тут есть свой прикол. Я даже использую это в таком случае:

Через makefile спускаю строку (имя файла) в зависимости от типа условной компиляции:

ADD_COMPILE_FLAGS += -DLOW_LEVELX_H=low_level3.h
...
CFLAGS += $(ADD_COMPILE_FLAGS)

определяю макрос:

// str macro
#define STR(S)                #S       // STR(blabla) = "blabla"
#define XSTR(S)                STR(S)   // STR(_version) = "v1.0" if _version = "v1.0"

А в программе просто подключаю инклюдом нужный файл без всяких там #if #elif #endif

#include XSTR(LOW_LEVELX_H)

Мне нравится.

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


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

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

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

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

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

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

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

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

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

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