ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
11 июля
380471
fk0, легенда (15.01.2013 14:52, просмотров: 3002)
Говнокод нового уровня. Хочу понять, оно в принципе имеет право на жизнь или нет (для GCC): В модуле file1.c делаем: const unsigned __NONAMED __attribute__((weak,section("NAME"))) = 521; В модуле file2.c делаем: const unsigned __NONAMED __attribute__((weak,section("NAME"))) = 354; В модуле file3.c, file4.c... и т.п. делаем аналогично. Только циферки везде разные, но их значение -- принципиально важно. В очередном модуле main.c, делаем: int main() { const unsigned N=__stop_NAME-__start_NAME; unsigned i; for (i=0; i<N; i++) { ИСПОЛЬЗУЕМ_ЧИСЛА(__start_NAME[i]); } ... return 0; } Компилятор для каждой секции NAME создаёт __start_NAME и __stop_NAME (начиная с каких-то версий GCC, если не создаёт -- объяснили ему это делать через скрипт для линкера). То-есть в чём суть. weak для всех __NONAMED позволяет обойти ошибку мол multiple definitions of один symbol in разные modules. Но при этом в область памяти соответствующей секции NAME все числа присвоенные множественным переменным __NONAMED попадают и их можно перебрать зная начало и конец секции. Может здесь какой-то косяк, который я в упор не вижу? Зачем это надо. Это позволяет решение принципиальной задачи: определить что-то в разных модулях, что между собой никак иначе не пересекается (не перечисляется где-то в третьем модуле, где можно попросту забыть перечислить). И потом использовать. Например реализовать вызов конструкторов а-ля C++, для конструктора достаточно только через макрос поместить ссылку на него в секцию NAME, без непосредственной ссылки из какого-то третьего C-файла. Зачем weak -- иначе все имена __NONAMED должны быть разные (что сложно обеспечить, даже через __LINE__, потому, что последний вполне может совпасть в разных модулях). Статическими __NONAMED быть не могут (без обращения к ним их компилятор выкинет), только глобальными. Насколько это реализуемо в других компиляторах? Без weak придётся, например, в каждом случае выдумывать вручную разные имена, непересекающиеся в разных модулях. Без возможности положить в нужную секцию -- делать asm("section, blablabla"). Что невозможно для сложных структур данных, но в простых случаях вполне терпимо. Больше ничего в голову не приходит.
[ZX]