[Trick] Автоматическое определение неиспользуемых заголовков
От: remark Россия http://www.1024cores.net/
Дата: 21.01.07 09:30
Оценка: 74 (4) :)
[M$ SPECIFIC]

Больше не надо никаких внешних тулзов и ручного вычищения неиспользуемых заголовков!

Допустим есть следующий заголовок некой библиотеки:
void lib_init();
void lib_deinit();
void lib_f();



Меняем заголовок на следующий:

template<int id> struct lib_helper 
{
    typedef int fake;
};

template<int id = 0> class lib_ind
{
    typedef typename lib_helper<id>::fake fake;
};

template<int id> struct lib_magic
{
    lib_magic()
    {
#ifdef _MSC_VER
        __if_not_exists(lib_helper<id>)
        {
            // Этот заголовочный файл включён зазря
            BOOST_STATIC_ASSERT(false);
        }
#endif
    }
};

static lib_magic<0> lib_magic_;


lib_ind<> lib_init();
lib_ind<> lib_deinit();
lib_ind<> lib_f();



Уаля! Если этот заголовок включит какая-либо единица трансляции, которая не вызывает ни одной из функций lib_init/lib_deinit/lib_f, то она не скомпилируется!

Несколько замечаний:
1. Этот заголовок можно использовать и с другими компиляторами, благодаря #ifdef _MSC_VER, просто не будет работать фича определения неиспользуемых заголовков
2. Если функции библиотеки должны возвращать какое-то значение, а не void, то это можно легко прикрутить к классу lib_ind, тогда просто функции будут выглядеть как lib_ind<bool> lib_init()
3. Всю эту бойду можно вынести в отдельный повторноиспользуемый заголовочный файл. Тогда в заголовке библиотеки надо будет написать примерно так:
PREVENT_UNUSED_HEADERS(my_lib_name);

4. Эту технику можно распространить и на заголовочные файлы, которые описывают классы. Но тут надо проявить немного фантазии, куда впихнуть lib_ind<>. Вообще место, куда впихнуть lib_ind<> в каждом конкретном классе, должно быть разным, и будет зависеть от того, что подразумевается под "использованием" класса, т.к. для классов это не так тривиально, как для функций. Например такой вариант:

template<int id = 0>
struct lib_class
{
    BOOST_STATIC_ASSERT(!id);
    lib_class(lib_ind<> fake = lib_ind<>());
};


требует обязательного создания экземпляров класса. Причём создание, например, указателей на класс не будет засчитываться за использование!
Или можно, например, все функции-члены записать аналогично свободным функциям:
struct lib_class
{
    lib_ind<> f1();
    lib_ind<> f2();
};




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: [Trick] Автоматическое определение неиспользуемых заголо
От: alexeiz  
Дата: 21.01.07 09:52
Оценка:
Здравствуйте, remark, Вы писали:

R>
R>    lib_magic()
R>    {
R>#ifdef _MSC_VER
R>        __if_not_exists(lib_helper<id>)
R>        {
R>            // Этот заголовочный файл включён зазря
R>            BOOST_STATIC_ASSERT(false);
R>        }
R>#endif
R>    }
R>};
R>


Не советую пользоваться __if_exists. В нем много багов, и скорее всего он не будет поддерживаться в ближайшем будущем: здесь
Re[2]: [Trick] Автоматическое определение неиспользуемых заг
От: remark Россия http://www.1024cores.net/
Дата: 21.01.07 10:16
Оценка: +1
Здравствуйте, alexeiz, Вы писали:

A>Не советую пользоваться __if_exists. В нем много багов, и скорее всего он не будет поддерживаться в ближайшем будущем: здесь


По поводу багов можно поподробнее. Ни разу не встречал, и на форуме вроде ничего такого не видел.

По поводу поста:
Ни в 2003, ни в 2005 пока не убрали. Да вообще то, что уже сделано обычно не убирают для совместимости.
По поводу перегрузок — это в данном случае абсолютно и не нужно.
Да вообще, судя по этому "once we have partial specialization __if_exists is likely to be deprecated" чувак слабо рубит в вопросе. Часть использований __if_exists действительно можно заменить частичными специализациями или sfinae. Но __if_exists обладает на порядок более мощными возможностями, которые ты ни с помощью частичных специализаций, ни с помощью sfinae даже близко не сделаешь. В частности то, что я привёл в этом топике, и ещё о паре применений собираюсь написать в скором будущем.
Тут у них получилось как с шаблонами в с++ — хотели сделать фичу для создания контейнеров, а сделали язык в языке.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: [Trick] Автоматическое определение неиспользуемых заг
От: alexeiz  
Дата: 21.01.07 10:37
Оценка:
Здравствуйте, remark, Вы писали:

R>Да вообще, судя по этому "once we have partial specialization __if_exists is likely to be deprecated" чувак слабо рубит в вопросе.


Этот "чувак", как ты выразился, является основным разработчиком компилятора Visual C++. Он еще и на засидания коммитета по стандартизации C++ от Майкрософта ездит (теперь вместе с Саттером, а до Саттера он один от Майкрософта там был). Так что кому, как ни ему об этом вопросе лучше знать.
Re[4]: [Trick] Автоматическое определение неиспользуемых заг
От: remark Россия http://www.1024cores.net/
Дата: 21.01.07 10:43
Оценка: -1
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, remark, Вы писали:


R>>Да вообще, судя по этому "once we have partial specialization __if_exists is likely to be deprecated" чувак слабо рубит в вопросе.


A>Этот "чувак", как ты выразился, является основным разработчиком компилятора Visual C++. Он еще и на засидания коммитета по стандартизации C++ от Майкрософта ездит (теперь вместе с Саттером, а до Саттера он один от Майкрософта там был). Так что кому, как ни ему об этом вопросе лучше знать.


Ну вот это же бред:

once we have partial specialization __if_exists is likely to be deprecated


partial specialization не является полной заменой __if_exists.
Ну ладно, спишем ему за давностью


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: [Trick] Автоматическое определение неиспользуемых заг
От: remark Россия http://www.1024cores.net/
Дата: 21.01.07 11:12
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, alexeiz, Вы писали:


R>partial specialization не является полной заменой __if_exists.

R>Ну ладно, спишем ему за давностью

alexeiz, с чем не согласен-то?
имхо, это как сказать, что когда у нас есть с-массивы, std::vector можно объявить deprecated

R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: [Trick] Автоматическое определение неиспользуемых заголо
От: Константин Л. Франция  
Дата: 21.01.07 14:57
Оценка: +2
Здравствуйте, remark, Вы писали:

радуешь своими ресёрчами, но неужели ты это в продакшн-коде предлагаешь использовать? А не проще ли, чем забивать код всякой ерундой, чтобы осмыслить принцып работы которой надо минут 5 (в зав. от сообразительности), комментить инклуды и компилять?
Re[5]: [Trick] Автоматическое определение неиспользуемых заг
От: Аноним  
Дата: 24.01.07 17:13
Оценка:
Здравствуйте, remark, Вы писали:

R>Ну вот это же бред:

R>

R>once we have partial specialization __if_exists is likely to be deprecated


R>partial specialization не является полной заменой __if_exists.

R>Ну ладно, спишем ему за давностью

Дело в том, что __if_exists был добавлен в компилятор в качестве временной альтернативы частичной специализации, т.к. реализовать его проще, нежели соответствующий стандарту механизм частичной специализации.

Будут ли его действительно убирать -- это вопрос. Раньше MS до последнего старалась сохранять все хоть кем-либо используемые фичи, независимо от их запланированности, надежности и политической верности.
Re: [Trick] Автоматическое определение неиспользуемых заголо
От: remark Россия http://www.1024cores.net/
Дата: 06.02.07 21:01
Оценка:
Здравствуйте, remark, Вы писали:

R>[M$ SPECIFIC]


Если кого это интересует, то это больше не M$ SPECIFIC, это 100% PURE C++ благодаря здесь
Автор: remark
Дата: 06.02.07



R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.