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

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
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
template <typename T> struct Pool { static std::vector<T> data; };

std::vector<tbphys::Body> Pool<tbphys::Body>::data;
std::vector<Ball>         Pool<Ball>        ::data;
std::vector<Wall>         Pool<Wall>        ::data;
std::vector<Bat>          Pool<Bat>         ::data;
std::vector<Brick>        Pool<Brick>       ::data;

template <typename T, typename U> struct List
{
	typedef T Head;
	typedef U Tail;
};

struct End {};

typedef List<tbphys::Body, List<Brick, List<Bat, List<Ball, List<Wall, End> > > > > Components;
typedef List<Brick, List<Bat, List<Ball, List<Wall, End> > > > DrawableComponents;
typedef List<Brick, List<Ball, List<Bat, End> > > MovableComponents;

const size_t badindex = size_t(-1);

struct GameBody
{
	size_t self,body,bat,brick,wall,ball;

	template <typename T> size_t& IndexOf ();
	template <> size_t& IndexOf <tbphys::Body> () {return body;}
	template <> size_t& IndexOf <Bat  >        () {return bat;}
	template <> size_t& IndexOf <Brick>        () {return brick;}
	template <> size_t& IndexOf <Wall >        () {return wall;}
	template <> size_t& IndexOf <Ball >        () {return ball;}

	template <typename T>
	T& AddComponent ()
	{
		size_t index = Pool<T>::data.size();
		Pool<T>::data.resize(index+1);
		T& result = Pool<T>::data[index];

		result.hostIndex = self;	
		IndexOf<T>() = index;
		return result;
	}

	template <typename T> void SetBadIndex ()
	{
		IndexOf<T::Head> () = badindex;
		SetBadIndex<T::Tail> ();
	}
	template <> void SetBadIndex <End> () {}
};

Сколько тут говнопаттернов крестоблядского крестоязыка?

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

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

    • Ну да, а где ещё? На крестофоруме меня крестозабанили, и из крестобани не особо покрестотроллишь.
      Кстати, странно, что из той крестотемы до сих пор не выложили сюда говноиерархию из трёх крестоклассов, в которой тоже участвовали крестошаблоны.
      Ответить
      • не понял, конечно, зачем стасики и зачем отдельные поля для размерности массивов
        но в порядке крестобреда можно и вот так сделать:
        http://ideone.com/3nkale
        Ответить
        • > и зачем отдельные поля для размерности массивов
          где?

          стасики тут как наиболее понятный мне способ представить данные так, чтобы было удобно сопоставлять типу данные. То есть чтобы можно было в шаблонном методе написать Pool<T>::data. что-то там...

          В Аде вот шаблонные модули для этого лучше приспособлены.
          Ответить
          • > где?
            body,bat,brick,wall,ball;
            что это?
            эти члены апдейтятся размером соответствующего массива минус один

            > стасики
            возможно, когда-нибудь ты отвыкнешь от глобальных переменных и однопоточности
            Ответить
            • Ты не понял. GameBody - не синглтон.
              Про глобальные переменные я где-то говорил уже.
              Ответить
              • >Про глобальные переменные я где-то говорил уже.
                Да про них все кому не лень говорят.
                Update: А, так ты "за"?
                Ответить
              • т.е. на один массив, скажем, Ball, натравливается сразу куча GameBody, каждый из которых себя регистрирует в этом массиве 0, 1 или более раз, с амнезией?
                и вычищать себя из массива им тоже не надо?
                Ответить
                • Нет, все регистрируют себя не более, чем по 1 разу. Как сделать проверку этого времени компиляции? Или это только в АТС можно удобно и немногословно сделать?
                  Ответить
            • >возможно, когда-нибудь ты отвыкнешь от глобальных переменных и однопоточности
              Всё правильно, но в уже ведь стадартизировали thread_local.
              Хотя вряд ли Тарас имеет в виду это.
              Ответить
              • по крестосекрету, крестотарас крестосидит на 2003 крестостудии, поэтому он наверняка крестоимеет в виду не это
                Ответить
                • >крестотарас
                  Осторожней.
                  Ведь сейчас где-то в крестоВселенной произошел сбой из-за деления на ноль, потом вылетел эксепшен и появилась новая черная дыра.
                  Ответить
                  • Сейчас в шоу-бизнесе модно выступать под альтернативным именем с альтернативным репертуаром, как Виктор Ургант или Виктор Билан.
                    Ждём крестолюба ViktorB.
                    Ответить
                    • Вспомнился хохлядский Виктор Павлик.
                      Хлопцi якщо зустрiнете його, то передайте нехай вже вирiшить хто ж вiн - Вiктор чи Павлiк.
                      Ответить
                    • Виктор? тут больше подойдет имя Эраст, ну или, на худой конец, Антон.
                      Хотя, учитывая, что ТарасБ - воин света и добра, он возьмет банальное Кристиан или Христофор.
                      Ответить
                      • В наших краях Эрастом себя никто бы звать не стал. Ровно как и Эдиком.
                        >ТарасБ - воин света и добра
                        Наоборот. Тарас - тролстлое, злое и безпощадное порождение Ады, а вот его брат-близнец как раз и должен быть добрым антиподом несущим свет, доброту и кресты в массы.

                        >Крестофор
                        for (int i=0;i<n;i++)
                        Ответить
                                  • извиняюсь, не UB, а тут бесконечный цикл будет. Ну т.е. unsigned integer underflow, хотя это не так называется
                                    Ответить
                                    • > то что все эти циклы с беззнаковыми i ведут к UB - это так задумано?
                                      unsigned underflow и overflow (в отличие от их signed аналогов ) вполне определены стандартом (иначе как писать всякую криптографию и прочие байтоебства?), и ни в коей мере не являются UB. Так что это просто вечный цикл.
                                      Ответить
                            • Но если честно, лучше бы они добавили подобные инициализаторы:
                              #include <stdio.h> 
                              int main(void) {
                                       int a[6] = { [4] = 29, [2] = 15 };
                                   int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
                                   int widthss[] = { 0 ... 9 };
                                      return 0;
                              }
                              http://ideone.com/5nVzSE
                              Ответить
                              • Пиздец.
                                >int i : boost::irange(0, n)
                                Неявное признание бустовцами того факта что питоновский for хорош, а for(;;) не нужен и может быть заменен while ( ну за исключением области видимости счетчика).
                                Ответить
      • > На крестофоруме меня крестозабанили
        ну всё пиздец, теперь запрещено называть дельфинов дельфинами, крестопроблемы - крестопроблемами, а негров - неграми
        уютненький остаётся последним оплотом здравого смысла и всеобщей доброты
        Ответить
        • А ещё там никогда нельзя было называть хуй хуем, пизду пиздой и ёблю ёблей.
          Ответить
          • ну все что ты перечислил - нецензурные слова
            а что плохого в назойливых крестопроблемах, кроме того, что они неразрешимые и ежедневно колют глаза?
            или в гладких и добрых дельфинах, которые так радуются, когда им почешешь лысую голову...
            кого это способно обидеть?
            Ответить
            • Ну просто с тех пор, как я получил крестобан, я решил, что это надо как-то использовать.
              Мои оппоненты неоднократно по старой привычке употребляли слова "да ты просто тупой дельфин, потому и не шаришь", ну и я решил, что у меня есть прекрасная возможность не тратить нервы на них, а просто сообщать обо всех случаях тому самому модератору, что выдал мне крестобан.
              После, кажись, третьего моего забаненного оппонента модератор и создал тему, что на дельфинов наезжать нельзя. Видимо, обеспокоился переполненностью тюрем.
              Ответить
                • Нисколько. Если они настолько тупые, что у них как у собаки Павлова "Тарас говорит о крестах - надо сказать что он тупой дельфин и не осилил кресты", даже если их знания ниже моих, то пусть сидят.
                  Ответить
                  • вместо того, чтобы героически нести знамя и за это первым всходить на эшафот, ты наябедничал воспитательнице и сделал плохо всем
                    и ведь теперь никто не узнает о новых крестопроблемах, старые со временем позабудут, упоминание дельфей в мировом интернете станет в точности 0 - что же ты наделал?
                    Ответить
                    • Нахрен мне эшафот упёрся? Не хочу я на эшафот, из него темы с новыми ответами не подсвечиваются красненьким.
                      И мне плохо не будет, я про крестопроблемы и так могу рассказывать, только не так толсто, ну и что?
                      Например, тут http://www.gamedev.ru/flame/forum/?id=169332 я разве на кого-то наехал?
                      Ответить
                      • в этом троллинге не хватает огня, 3/10
                        посмотри, даже у нуба недостаточная степень батхёрта
                        и вообще, флейм без дельфинов и крестопроблем - секс с резиновой женщиной в противогазе
                        Ответить
        • defecate-plusplus
          >ну всё пиздец, теперь запрещено называть дельфинов дельфинами, крестопроблемы - крестопроблемами, а негров - неграми
          http://www.gamedev.ru/flame/forum/?id=169380

          А вообще кто-ты такой? Как ты раньше меня заметил тему? Я заметил только после твоего поста.
          Пойду читать. Запасся попкорном.
          Ответить
  • Тарас, что за трэш ты написал? Нахрена всё это? Где же старые добрые абстрактные фабрики?

    P.S. У тебя объявлены typelists, но они нигде не используются. Запости код, в котором они используются, наверняка там можно словить лулзов.
    Ответить
  • Вся эта байда пошла от изначального отказа от виртуальных функций, наследования, динамических кастов и прочего оопешного говна.
    Вот начало этой веселухи: http://www.gamedev.ru/flame/forum/?id=167890
    Ответить
    • Лол. Годный креатив.
      Правда возникают вопросы: "А нахуя?" и без конкретного примере непонятно зачем такое говно вообще надо?
      Дальше по треду запахло фабриками фабрик и я перестал читать.
      Ответить
      • Там в теме, как раз перед фабриками, я кинул ссылку на проект, в котором это используется.
        Я хотел сделать богомерзские полиморфные объекты с виртуальными функциями, но магистр Крестосвета Пушков наставил меня на путь истиный.
        Сначала я для каждого типа компонента писал свою процедуру добавления, потому что они по разному назывались и объединить их во что-то единое не получалось. Но я вспомнил про специализацию шаблонов и смог на списках типов сделать то, что хотел!
        Ответить
  • В общем, потратив неделю на божественную архитектуру на шаблонах, не содержащую ни одного виртуального метода или какого-либо преобразования объектов, я понял, какой же божественный язык этот С++. Да, народ, всё-таки надо признать, что Дельфи - это говно. Если бы я делал этот проект на Дельфи, то на первом же неявном преобразовании я бы сделал его не задумываясь, поэтому никакой архитектуры у меня бы не было.
    Если бы я по-прежнуму был жалким дельфином, я бы за эту неделю добавил уровни, всякие фичи, запилил бы меню и бонусы, а кому это надо? Кому бы я потом смог похвастаться на форуме своей изъёбистой архитектурой? Ну ладно, если я это делаю для себя, а если бы я это делал по работе, то чем бы я ебал мозг заказчику? Только С++ предоставляет программисту возможность заполнить написанием программы сколько угодно длительный промежуток времени! В С++ есть для этого всё: куча различных возможных извращений, долгая копиляция, хитрый синтаксис, возможноть поделить 1 на 2 и получить ноль.
    А Дельфи... Чем может похвастаться это галимое убожество?
    Ответить
    • Оно и понятно - тебя на геймдеве зобанели и ты пришел высказаться сюда.
      Непонятно другое - "за что банить?". Это ж весело читать.

      >Только С++ предоставляет программисту возможность заполнить написанием программы сколько угодно длительный промежуток времени!
      Parkinson law in action.
      Ответить
      • Забанили в другой крестотеме, за моё крестозлорадство по поводу одного крестобага одного (и даже нескольких) крестокомпилятора.
        Ответить
    • Ты должен мне новый монитор, старый треснул от жира.
      Ответить
      • Да, а ещё отсутствие проверок в vector::[] даже в отладочном режиме, тоже полезная вещь, чтобы было не скучно. Походу придётся мне в std лезть и всё править (перезаходить под админом, потому что под пользователем лезть в папку студии нельзя). А чё, я уже правил, потому что там был баг, из-за которого стл то ли не компилировался, то ли поносил предупреждниями в православном режиме -noexceptions.
        Ответить
        • А в Виндовсе нет какого-нибудь Секьюрити-Инхансед-Виндовс? У меня просто на экскремены исходит, если такое сделать. Потом не отмашешься.
          Ответить
        • Паттерн тут всего один - метапрограммирование шаблонов, не? Правда boost::mpl автор ниасилил.

          > Да, а ещё отсутствие проверок в vector::[] даже в отладочном режиме
          У тебя же какая-то древняя студия. Они в какой-то момент переключились на STLPort, там есть макрос _STLP_DEBUG, который включает такую проверку.
          Ответить
        • в студии поновее проверки в vector::operator[] есть, вызывался abort() в случае выхода за границы, не помню точно в какой версии это было
          Ответить
  • А вот как я этим пользуюсь:
    #define ListFunc(Name,ParamType,Param,Action) \
    	template <typename L> \
    	void Name (ParamType Param) \
    	{ \
    	typedef L::Head T; \
    	Action \
    	Name<L::Tail> (Param); \
    	} \
    	template <> \
    	void Name <End> (ParamType) {}
    
    
    ListFunc(KillBadComponents, , , 
    	std::vector<T> &v = Pool<T>::data;
    	size_t j=0;
    	for (size_t i=0; i<v.size(); ++i)
    		if (v[i].hostIndex < badindex)
    		{
    			if (j<i) MoveComponent<T> (i,j);
    			++j;
    		}
    	v.resize(j);
    	)

    Жаль, что работает лишь для функций 1 параметра

    Божественный язык...
    Ответить
  • 6 за
    3 против
    настоящее искусство никогда не бывает однозначно хорошим!
    Ответить
    • >Скажем так, мне не удалось получить положительный КПД от всяких там типа высокоуровневых фич.
      Так даже в убогой джаве можно с женериками дойти до безумия.
      #11878
      У меня много раз на практике были случаи когда женерики давали отрицательный кпд - собственно когда у класса 3 и больше параметра - это уже хуйня.
      Иногда проще их не писать, заткнуть ворнинг и откастить явно, кода всего-то навсего 3 буквы.
      > (T)
      Чем дрочиться с кучей женериков, которые в яве далеко неидеальны. Тем более там нету var, auto что добавляет пиздеца.

      http://habrahabr.ru/post/153225/
      http://eax.me/haskell-bread-task
      http://habrahabr.ru/post/153845/

      Не в тему, но тоже оверинжининг. Тебе должно понравится.
      И снова сорри за хаброту.
      Ответить
      • В общем, Дельфи-7 - оптимальный язык, кроме шуток.
        Ответить
        • Если бы ты сказал Ада я бы понял. Так вообще ассемблер - идеальный язык, кроме шуток.
          Можно даже с передаваемыми аргументами дойти до безумия.
          Кстати тоже эмпирическое правило - когда в методе более 3-х аргументов в большинстве случаев он говно.

          Но из этого ж не следует что языки допускающие 42 аргумента - говно.
          А языки где можно передать только 1 аргумент - оптимальны.
          Ответить
          • Языки, где можно передать лишь 1 аргумент, удобны для метапрограммизмов.
            Ответить
      • кстати, про пека рей мне статьи понравились
        показательно
        Ответить
      • Некоторые люди никак не могут понять, что шаблоны проектирования - это средство рефакторинга, а не проектирования (да, копетан негодуэ). Сначала пачкаем руки, выбрав алгоритмы и разрабатывая код, потом причёсываем, устраняя копи-паст и неоптимальности-"технические задолженности".
        Ответить
        • >это средство рефакторинга, а не проектирования
          откуда инфа? где почитать?
          Ответить
          • Многие, начиная с Брукса, пишут, что первая реализации системы всегда годится разве что на выброс. Проблема в том, что люди не понимают до конца предметную область и многих потенциальных проблем, не начав писать код.
            Конечно, план и начальный дизайн (мне кажется правильным слово "модель") очень нужны, без них вообще ничего не сделаешь. Но это не тот уровень, где нужны шаблоны: тут нужно выделить сущности, разработать алгоритмы и принять ограничения, наложенные на систему. Но до абстрактных фабрик, в моём представлении, на этом уровне дело дойти не должно.
            Мне близок подход "bottom up", исповедуемый многими практиками. Сделай сначала что-нибудь, а потом уже улучшай, дорабатывай и выделяй абстракции. Главное - не бояться переписывать код.
            Ответить
  • кстати, раз это теперь тред флейма, докладываю - на brainbench сегодня день бесплатного пиписькомерства
    так что все крестобляди, джавобляди и шарпобляди (прости, Тарас, дельфей там почему-то нет, хотя есть даже кобол) могут найти интересующую их линейку и бесплатно без смс (но с регистрацией) замерить и сравнить с эталоном из палаты мер и весов
    http://www.brainbench.com/xml/bb/common/testcenter/freetests.xml
    Ответить
    • Это ад, сущий ад. Держа в руках стандарт (благо им не запретили пользоваться), еле как ответил на жалкие 4.67 балла. В очередной раз убеждаюсь, что с++ я не знаю...

      P.S. Вот интересно, что не так в этих строчках:
      template <class C, class T> void foo(C op1, T op2) {}
      template <class T, class C> void foo(T op1, C op2) {}
      template <class C, class T> void foo(T op1, C op2) {}
      Варианта "все три нормальны" не было.
      Ответить
        • Бля вот оно че, они все три в одном коде! А меня что-то заклинило, что их нужно рассматривать по-отдельности, и я впал в ступор.

          Спасибо!
          Ответить
          • я там зафейлился на сложных примерах, когда иерархия вымучена из 4 классов, вперемешку с множественным наследованием и виртуальным наследованием
            3 минут не хватает чтобы расписать на бумажке кто от кого и в каком порядке

            ну и у них там есть явно бажный пример, когда минимум два варианта верны:
            мол, выберите, что не скомпилируется
            char s[] = "string";
            char * const cp = s;
            cp[3] = 'a'; // компилируется
            std::cout << cp << std::endl;
            char * p;
            const char * const ccp = p; // аналогично
            Ответить
            • А там, если не изменяет память, не про само const char *const ccp=p спрашивали, а про написанное ниже ccp=..., которое уже обломается.

              P.S. Или там полно похожих вопросов?
              Ответить
                • А у меня в подобном вопросе были перечислены 5 строчек похожих на ваши, а потом в каждом варианте ответа еще по строчке. И вот из них действительно только одна скомпилировалась бы. То ли cp = s, то ли cp[3] = 'a', не помню, если честно, с какой стороны от звездочки const стоял у cp.
                  Ответить
                    • Аватар и стиль речи подсознательно мешают написать тебе "ты". Как сказали на ЛОРе: "Если ты видишь на аватарке кота, то ты тоже думаешь, что разговариваешь с котом?"
                      Ответить
      • > на жалкие 4.67 балла. В очередной раз убеждаюсь, что с++ я не знаю...
        Да Вы зажрались, товарищ.

        С 4.67 в топ-10 по абсолютному\региональному рейтингу не вошли случайно?
        Ответить
        • это, видимо, 4 ошибки из 40
          у меня 3 и 4.76

          потом начал проходить второй раз, вопросы очень сильно повторяться начали, неспортивно
          Ответить
          • Там же таймаут раньше был на пересдачу одного и того же теста, что-то вроде 6 или 8 месяцев... Второй раз уже было не так интересно...
            Ответить
        • Так это с подглядками в доки. Я вот часть вопросов по stl'ным функциям без мана не ответил бы... ну не помню я их названий, мне проще искать их в списке, если они мне нужны.
          Ответить
      • >второй дублирует первый
        Даже если второй вариант удалить, то при инстанцировании при выборе между 1ым и 3им должна быть амбигити. Так что эти варианты нормальны только по отдельности. Как разные перегрузки не канают.
        Ответить
        • амбигити между 1 и 3 будет, только если оба типа аргументов одинаковы
          типа foo<int, int>(...)
          в общем случае компилятор съест это определение
          а 1 + 2 не съест уже просто после декларации
          Ответить
          • Будет проблема при вызове функции без указания параметров шаблона, тогда "выведи сам" не сработает.
            Ответить
            • ты всё правильно говоришь
              но вопрос стоял именно так - в каких из этих трех строк компилятор начнет ругаться уже сейчас
              Ответить
    • вот кстати смех смехом
      а дельфийный отдел до сих пор не может нового сотрудника найти
      даже с целью дообучить в процессе
      Ответить
        • на моей работе
          да думаю, такая проблема везде, где осталась разработка на дельфях
          Ответить
          • Я надеюсь, там не очередное "приветствуются знания оракула"?
            Ответить
            • приветствуется
              базы данных дельфинам разрабатывать никто не даст, но понимать, как вызвать по имени хранимую процедуру и отобразить полученные данные в гриде он должен
              на дельфях сейчас только и делают, что толстые клиенты, ты не знал?
              Ответить
                • а ты как думал?
                  игры на дельфи?
                  тотол коммандёр безплаттно без смс?

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

                  но наши дельфины самостоятельно sql не пишут, более того, это порицается
                  только вызов хранимых процедур, заботливо написанных для них нашими ораклоидами
                  только хардкор
                  Ответить
                  • > на самом деле, знание теории бд и практики очень помогает в жизни и прибавляет к зарплате
                    Можно даже не учить ЯП, а знать только бд и прилегающие декларативные языки... Никогда не забуду одного BI девелопера, который при виде .NET кода в скриптах сразу умывал руки.

                    > только вызов хранимых процедур, заботливо написанных для них нашими ораклоидами
                    blessed way by Microsoft and Oracle inc. для толстых клиентов

                    > только хардкор
                    Хардкор был бы в прямых запросах к БД.
                    Ответить
          • Скоро дельфисты будут получать больше чем было в 90-е?
            Только из-за того что все повымерли и/или переучились на пыху с решеткой.
            Хитрый план Тараса?
            Ответить
              • пруф?
                знакомый кума свояка на базаре слыхал, что на Коболе всех съели и запили сайлонским чаем
                Ответить
                • а что тебя удивило? разрыв шаблона?
                  жирный капитализм в том и состоит, что пока есть дойная корова (бизнес-продукт на коболе, до сих пор приносящий прибыль), будут нужны единицы 1/млн, чтобы это говно поддерживать
                  Ответить
                  • удивило отсутствие пруфа
                    как и в прочих городских легендах присутствует правдоподобный элемент - GB не самое приятное место в плане налогов
                    Ответить
      • моя думать, что этот тред полон рыбацких историй
        на самом деле
        > с целью дообучить в процессе
        также означает потолок вознаграждения
        вот и не клюет
        Ответить
        • я всё точно описал - не может найти ни готового, ни на поруки
          зарплаты рыночные, московские
          придет готовый опытный специалист - будет получать по рынку как готовый опытный специалист
          придет перспективный - будет получать как перспективный
          Ответить
          • ты выше озвучил волшебное слово - жирный капитализм
            это наводит на мысли о том, что у вашего CFO свое особое мнение о рыночных зарплатах
            если даже стажеров позиция не привлекает...
            Ответить
            • как тебе сказать
              себе нового крестовика я нашёл за 2 недели, как была дана отмашка - в связи с расширением срочно найти траляля
              в консалтинг тех писателя нашли за месяц
              даже нового тестера нашли
              а дельфины всё ищут, вот уже 2 месяца ищут

              какая сейчас рыночная зарплата для приличного дельфина, принимаемого на работу? - 70-120к, я думаю
              для малограмотного дельфина - в районе 50, плюс минус десятка, в зависимости от его малограмотности
              т.е. вряд ли сильно отличается от вилок для с++

              и да, за эту волну собеседований я таких образчиков насмотрелся, что таких стажеров я бы и за бесплатно не взял
              Ответить

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

Переведи на "PHP", guest!

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


    8