Кресты / Говнокод #2556 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
//Обьявление класса в хедере с последующей реализацией:
template<class TConstructStrategy>
class TClass
{
public:
	TConstructStrategy __ctor;
                  //...Прочие методы...
};

//...Реализация прочих методов класса...

//================================================================

//Конструктор с переменным числом параметров, типа функтор:
//Тоесть обьявлено где-то в коде проекта и передаётся, как параметр при конструировании.
typedef void TConstract(int a);
template<>
TClass<TConstract>::TClass(int a)
{
	//doing...
};

int main(int argc, char* argv[])
{
          //...
          TClass<TConstract> A(5);
          //...
}

Это говнокод, но не результат работы над проектом, а результат насмешек над компилятором MSVC 6.0.
Основано на обявлении типа-функции:
typedef void TConstract(int a);, но тк конструктор не функция - используется внутренее имя конструктора MSVC6.0:
void __ctor(void);, согласно которому он всё-таки функция.
__dtor - "внутренее" имя деструктора, кстати.
Спалить "секретное" имя обычно можно в сообщениях об ошибках c участием этих имён. При входе в конструктор/деструктор через отладчик под дизасемблером(наверное). В стеке вызовов отладчика(наверное). Наверное ещё как-нибудь, например проходом HEX редактора по экзешнику компилятора и прилижащим dll...
Итак для обсуждения (хотя и не собираюсь это использовать):
1)Как ещё, кроме странных пергрузок, представленного выше метода конструктора-функтора, и вызовов типа A.__ctor(); / A.__dtor() это можно использовать?
2)Какие "скрытые" имена конструкторов/деструкторов у других компиляторов? Я пробовал в MSVC6.0. В MSVS 2008 при первом расмотрении "внутреннее" имя другое и сходу не палится.
Для примера приведу метод с "обычным" функтором (на самом деле он не самый обычный):

//Обьявление класса в хедере с последующей реализацией:
template<class TStrategy>
class TClass
{
public:
	TStrategy func;
                  //...Прочие методы...
};

//...Реализация прочих методов класса...

//================================================================

//Функтор:
//Тоесть обьявлено где-то в коде проекта и передаётся, как параметр при конструировании.
typedef void TFunc(void);
template<>
void TClass<TFunc>::func(void)
{
	//doing...
};
int main(int argc, char* argv[])
{
          //...
          TClass<TFunc> A;
          A.func();
          //...
};

Запостил: fake_guest fake_guest, (Updated )

Комментарии (19) RSS

  • Пришлось перенести часть описания "говнокода" в комментарий, тк оно не поместилось...
    "Обычный" функтор TClass<TFunc> A; компилируется во многих компиляторах, более или менее соответсвующих стандарту.
    Продолжаем обсуждение, но уже относительно "обычного" функтора(приведенный чуть выше код), тк всерьёз задумываюсь над его использованием :
    3)Это говнокод и использовать его не стоит?
    4)Какие ещё интересные применения можно найти для типов-функций typedef void TFunc(void);?
    Ответить
    • Использование внутреннего имени __ctor конструктора в компиляторе для перегрузки.
      Ответить
  • Чуть не забыл, функтор, как и функтор-конструктор, также с переменным числом параметров.
    Обнаружил ошибочку функтора (в конструкторе она тоже есть). Хотя исправляется легко.
    template<class TStrategy>
    class TClass
    {
    public:
    	TStrategy func;
    };
    
    //Функторы с переменным числом параметров:
    typedef void TFunc(void);
    template<>
    void TClass<TFunc>::func(void)
    {
    	//doing...
    };
    
    
    typedef void TFunc2(void);
    template<>
    void TClass<TFunc2>::func(void)
    {
    	//doing...
    };

    В выше приведённом коде не удаётся обьявить второй функтор с тем же числом параметров в том же CPP-файле. Пишет, что мол уже обьявлен. Исправляеться легко:
    template<class TStrategy>
    class TClass
    {
    public:
    	typename TStrategy::TFunction func;
    };
    
    
    //Функторы с переменным числом параметров:
    struct TFunc
    {
    	typedef void TFunction(void);
    };
    template<>
    void TClass<TFunc>::func(void)
    {
    	//doing...
    };
    
    
    struct TFunc2
    {
    	typedef void TFunction(void);
    };
    template<>
    void TClass<TFunc2>::func(void)
    {
    	//doing...
    };
    	//...
    	TClass<TFunc> A;
    	A.func();
    	TClass<TFunc2> B;
    	B.func();

    Единственное, для различных компиляторов нужно правильно расставить ключевое слово typename. Например, для MSVC6.0 оно вообще не нужно.
    Ответить
  • Не осилил, много букв. Выложи свой опус в каком-нибудь форуме для ботанов
    Ответить
    • Удостоверяю. Здесь действительно его нет. __ctor - не С++. 😉
      Ответить
      • Из всего приведенного кода только __ctor показалось похожим на ключевое слово C++? 😉
        Ответить
    • Предлагаю за немотивированный вопрос "Где здесь C++?" банить по IP. Шутка поднадоела.
      Ответить
  • За издевательства над компиляторами однозначно +

    Жаль, но такой код не переносим. Почитал стандарт, и вот что там сказано про шаблоны:
    14.3.1/3:
    If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [Example:

    template<class T> struct A {
    static T t;
    };
    typedef int function();
    A<function> a; // ill-formed: would declare A<function>::t
    // as a static member function


    --- end example]

    В переводе на русский - функциональный тип нельзя использовать при объявлении функций в шаблонах. Но можно в обычных классах. Интересно почему именно так?
    Ответить
  • тема интересная, но накуя это _здесь_ постить???
    Ответить
  • Ой давайте не будем про MSVC 6.0 оно родилось когда Я ещё в школу ходил. А наш ебанутый заказчик настаивает на том что бы на нём проект писали, ну вот и пишем уже 3- года будет. Вы не видели там мой шаблонный "адоптированый" под древний компилятор код с матюками в коментариях. Хуле там.. заказчик не пробиваемый. А в проекте изменение порядка хидеров например может привести к INTERNAL COMPILER ERROR.
    Поэтому там в инклюд секции так и написано - "не трогай блядь...., я эту причину два дня искал" 🙂
    Во общем пора наверно валить с этого проекта, засиделся Я там, да и заказчик не пробиваемый жлоб и идиот.
    Ответить

Добавить комментарий

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8