- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
class SMemManager {
public:
SMemManager() { std::cout<<"Singleton new: "<<this<<std::endl; init(); }
void* operator new(size_t) { return (void*)p_body; }
void operator delete(void* ) { }
private:
void init() {
if (p_init!=0xF3149A51) {
p_countMemData=0;
p_memData=0;
std::cout<<"Singleton init: "<<this<<std::endl;
}
p_init=0xF3149A51;
}
unsigned int p_init;
unsigned int p_countMemData;
void ** p_memData;
static char p_body[];
};
char SMemManager::p_body[sizeof(SMemManager)];
Один из эпичных синглтонов от foxes.
Посмотреть эволюцию этого шедевра или окунуться в его обсуждение можно в теме по ссылке:
http://www.gamedev.ru/code/forum/?id=211629&page=6#m81
Soul_re@ver 09.03.2016 19:05 # 0
Ещё весело то, что это вообще не синглтон ни разу.
Xom94ok 09.03.2016 20:54 # +2
Ну а какой синглтон можно считать православным и чтоб при этом бомжиками не пах? Чаще всего я вижу такой: Но, накушавшись проблем с порядком инициализации, делаю теперь так:http://ideone.com/cFVPiO
1024-- 09.03.2016 21:09 # 0
А почему не простой вариант с проверкой?
Из-за производительности? Или тоже как-то порядок инициализации ломается? (Хотя, как? Наоборот, он правильнее будет, т.к. зависимые сущности вызовут того, от кого зависеть строго раньше завершения своего создания)
Xom94ok 09.03.2016 22:09 # +3
Дополнительным плюсом стало то, что объекты создаются именно в том порядке, в котором они объявлены в коде, т.е. легче трейсить код и читать логи.
Soul_re@ver 09.03.2016 21:11 # 0
Ассерты не решение: их нет в продакшене, отстрелить ногу это всё же даст.
Xom94ok 09.03.2016 22:31 # 0
> нужно быть внимательным с очерёдностью удаления
Нунах, пусть за меня RAII работает.
> Ассерты не решение
Всего лишь компилируемость кода в релизе - достаточный критерий для его прохождения в мастер ветку? Ну, пиздец, хотя такие личности мне встречались.
Ладно, хуй с ним, синглетоном. Всем добра и обнимашек!
Soul_re@ver 09.03.2016 22:50 # 0
А если прописать ограничения на работу с синглтоном, то Мейерсовский покатит.
roman-kashitsyn 09.03.2016 22:17 # 0
Чего? Синглетон со статической переменной в функции - самый кошерный. Начиная с C++11 он ещё и потокобезопасен из коробки. Инициализация автоматическая будет при первом использовании.
Возможно, ты хотел сказать "порядок уничтожения", а не "порядок инициализации".
Xom94ok 09.03.2016 22:45 # +1
На эльбрусе нет 11-х крестов, и не будет ещё очень скоро :) В QNX нейтрино есть лишь частичная поддержка, и та - неофициально.
> Возможно, ты хотел сказать "порядок уничтожения", а не "порядок инициализации".
Я имел ввиду именно порядок инициализации, уже отписался про инициализацию из другого потока.
Кстати, да. Порядок уничтожения тоже нужен вполне определенный. Сходу пример на Qt не сгенерирую, но его суть можно свести к простому правилу: все QObject-ы надо уничтожить до уничтожения QApplication.
Bobik 09.03.2016 22:50 # 0
roman-kashitsyn 09.03.2016 23:55 # +1
Но pthread_once() для защиты конкуррентной инициализации можно юзать уже сейчас
> Порядок уничтожения тоже нужен вполне определенный
Александреску по этому поводу целую секцию написал в "Модном ЦПП Дизайне" полтора десятка лет назад.
Xom94ok 10.03.2016 00:28 # 0
Ок. Ты - умный, помнишь этот фрагмент. Я - тупой и не смог прочесть и осознать книгу полностью.
Вот код, приводящий к сегфолту по выходу:
Antervis 10.03.2016 07:47 # 0
foxes 10.03.2016 18:27 # −3
>struct Singletone {
> static Singletone & instance() { static Singletone s; return s; }
>};
Вот я твой код в говнокоды запишу и буду таким же идиотом как -Eugene-.
Saehrimnir 28.10.2020 20:21 # 0
foxes 31.10.2020 14:41 # +6
CHayT 31.10.2020 15:42 # 0
foxes 31.10.2020 15:12 # +2
bormand 31.10.2020 15:15 # 0
Но UB здесь всё равно есть т.к. буфер из char'ов не гарантирует достаточного выравнивания для полей данного класса.
foxes 31.10.2020 15:22 # 0
Выравнивание адреса p_body это вообще другой вопрос.
bormand 31.10.2020 15:23 # 0
Не размер, а выравнивание (alignment). Не на всех платформах void* и int можно читать с кривых адресов. Да и на amd64 может пиздануться если конпелятор надумает заюзать sse.
foxes 31.10.2020 15:30 # 0
foxes 31.10.2020 15:42 # 0
bormand 31.10.2020 15:49 # 0
Ну да, атрибутом на p_body должно решиться.
foxes 31.10.2020 15:54 # 0
gost 31.10.2020 15:58 # −1
foxes 31.10.2020 15:59 # 0
gost 31.10.2020 16:03 # 0
foxes 31.10.2020 16:10 # 0
gost 31.10.2020 16:15 # +2
Разумеется, попытка набрать анскильных «программистов» на «C++» и прикрыть их анскильность опциями компиляторами — это заранее обречённый пердёж в лужу.
guest8 31.10.2020 16:21 # −999
gost 31.10.2020 16:34 # 0
Повесился бы.
В те тёмные времена, если мне память не изменяет, Стандарт вообще не упоминал выравнивания, поэтому надеяться можно было только на крепость рук, на руки друга и вбитый крюк, и молиться, чтобы компилятор не подвёл.
bormand 31.10.2020 16:36 # 0
Да ладно... Я просто делал такие буфера с запасом и потом поинтер округлял вверх. Некрасиво, но жить можно.
guest8 31.10.2020 18:25 # −999
guest8 31.10.2020 18:22 # −999
foxes 31.10.2020 16:21 # 0
guest8 31.10.2020 16:23 # −999
guest8 31.10.2020 17:31 # −999
CHayT 31.10.2020 17:53 # +2
BoJlLLle6HuLLa 31.10.2020 18:09 # +3
j123123 31.10.2020 18:16 # +2
guest8 31.10.2020 16:07 # −999
bormand 31.10.2020 16:07 # 0
foxes 31.10.2020 16:12 # 0
https://ideone.com/wgf1UK
guest8 31.10.2020 16:21 # −999
foxes 31.10.2020 16:25 # 0
guest8 31.10.2020 16:30 # −999
foxes 31.10.2020 16:33 # 0
gost 31.10.2020 16:39 # 0
§ 6.9.3.3/8
bormand 31.10.2020 16:00 # 0
А есть другие варианты? Какую там опцию надо включить у gcc чтобы он зафорсил всем глобалкам выравнивание на N?
guest8 31.10.2020 16:03 # −999
bormand 31.10.2020 16:04 # 0
foxes 31.10.2020 16:17 # 0
guest8 31.10.2020 16:19 # −999
bormand 31.10.2020 16:24 # 0
Не работает. Вот такой код со всеми вариантами этой опции криво выровнен на amd64:
foxes 31.10.2020 16:38 # 0
А на твоей платформе должно?
bormand 31.10.2020 16:44 # 0
Короче я теперь вообще не понимаю что эта опция делает.
gost 31.10.2020 16:54 # 0
bormand 31.10.2020 17:07 # 0
Что эта опция вообще делает?
j123123 31.10.2020 16:54 # 0
Зачем, зачем? Почему не сделать тип с нужным выравниванием typedef uint8_t uint8_t_align8 __attribute__ ((aligned (8))); допустим
и потом делать глобалки с таким типом ?
bormand 31.10.2020 17:00 # 0
j123123 31.10.2020 17:03 # 0
foxes 31.10.2020 18:28 # 0
gost 31.10.2020 18:42 # 0
Ну и в любом случае, на уровне языка никаких «-O1» нет, поэтому запись в невыровненные переменные всё равно будет UB.
guest8 31.10.2020 18:47 # −999
gost 31.10.2020 19:01 # 0
alignof(T) требует, это ID.
foxes 31.10.2020 18:48 # 0
guest8 31.10.2020 18:50 # −999
foxes 31.10.2020 18:54 # 0
guest8 31.10.2020 18:55 # −999
foxes 31.10.2020 19:04 # 0
guest8 31.10.2020 19:12 # −999
foxes 31.10.2020 19:17 # 0
guest8 31.10.2020 19:25 # −999
gost 31.10.2020 19:02 # 0
foxes 31.10.2020 19:04 # 0
gost 31.10.2020 19:07 # 0
foxes 31.10.2020 19:13 # 0
j123123 31.10.2020 19:15 # +1
Это где ты такое прочитал? https://stackoverflow.com/a/506590
> The alignment has the following guarantee from the standard (3.7.3.1/2):
> The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function).
Т.е. выровнено так, чтоб любую хуйню туда норм было писать, если говорить простым языком
gost 31.10.2020 19:24 # 0
§ 7.6.2.7.18, N4842
j123123 31.10.2020 19:08 # 0
foxes 31.10.2020 19:14 # 0
j123123 31.10.2020 19:17 # 0
foxes 31.10.2020 19:23 # 0
gost 31.10.2020 19:26 # 0
guest8 31.10.2020 19:26 # −999
foxes 31.10.2020 19:27 # 0
gost 31.10.2020 19:31 # 0
Вот, в этом и есть вся проблема. А сделать так, чтобы он знал, очень просто:
Вот, теперь ты имеешь полное право записать в q инт.
Ещё правильнее, конечно, использовать std::aligned_storage.
foxes 31.10.2020 19:33 # 0
gost 31.10.2020 19:36 # 0
bormand 31.10.2020 19:39 # +1
guest8 31.10.2020 19:41 # −999
bormand 31.10.2020 19:53 # 0
guest8 31.10.2020 19:56 # −999
foxes 31.10.2020 19:43 # 0
gost 31.10.2020 19:48 # 0
С кодовой базой, которая компилируется только на gcc 3.0 и рефакторингу не подлежит, можно сделать только одну разумную вещь: переместить на дискету, дискету выкинуть в мусорное ведро, мусорное ведро передать уборщице.
gost 31.10.2020 18:59 # 0
guest8 31.10.2020 19:04 # −999
gost 31.10.2020 19:06 # 0
guest8 31.10.2020 19:29 # −999
gost 31.10.2020 19:33 # 0
Да, именно. Чтобы такой хуйни не было — компилятор с оптимизирующими опциями выравнивает любые переменные — включая массивы байтиков — по размеру слова. Разумеется, менее UB невыровненный доступ от этого не становится.
guest8 31.10.2020 19:53 # −999
foxes 31.10.2020 19:08 # 0
guest8 31.10.2020 19:17 # −999
guest8 31.10.2020 19:19 # −999
foxes 31.10.2020 19:25 # 0
gost 31.10.2020 19:28 # 0
foxes 31.10.2020 19:30 # 0
guest8 31.10.2020 19:34 # −999
foxes 31.10.2020 19:42 # 0
guest8 31.10.2020 19:44 # −999
foxes 31.10.2020 19:46 # 0
gost 31.10.2020 19:50 # 0
Всё, что можно сделать с кодом с UB — это превратить его в код с ID, если документация конкретной версии конкретного компилятора явно постулирует, что такое-то поведение определено.
foxes 31.10.2020 19:57 # 0
alignas(int) char q[11 + sizeof(int)];
Чтобы получить нормальный код.
А теперь выходить это тоже UB?
guest8 31.10.2020 19:59 # −999
foxes 31.10.2020 20:02 # 0
guest8 31.10.2020 20:03 # −999
guest8 31.10.2020 20:07 # −999
guest8 31.10.2020 20:10 # −999
guest8 31.10.2020 20:25 # −999
guest8 31.10.2020 20:28 # −999
guest8 31.10.2020 20:42 # −999
foxes 31.10.2020 20:15 # 0
guest8 31.10.2020 20:35 # −999
j123123 31.10.2020 20:55 # 0
На его сайте написано:
> ⚫ 2003 - 2008 г. МГУПИ
Московский государственный университет приборостроения и информатики
(высшее)
Получается что лет 18 назад.
guest8 31.10.2020 20:57 # −999
j123123 31.10.2020 20:58 # 0
guest8 31.10.2020 20:59 # −999
j123123 31.10.2020 21:00 # 0
guest8 31.10.2020 21:01 # −999
guest8 31.10.2020 20:59 # −999
j123123 31.10.2020 21:02 # 0
Вот к чему байтоебство приводит.
Какой багор )))
На самом-то деле 10 лет назад.
j123123 31.10.2020 21:13 # 0
guest8 31.10.2020 21:22 # −999
guest8 31.10.2020 21:25 # −999
j123123 31.10.2020 21:34 # 0
guest8 31.10.2020 21:02 # −999
j123123 31.10.2020 20:03 # 0
Про реальную проблему я уже вроде давал ссылку
см. https://govnokod.ru/27068#comment589971 --> https://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-x86.html
guest8 31.10.2020 20:04 # −999
gost 31.10.2020 19:44 # 0
Это делается очень просто. Пусть есть код:
На архитектуре, которая может читать только по четыре байта, компилятор положит q по адресу, кратному четырём байтам. А дальше произойдёт магия (псевдоасм, на endianness похуй):
Вуаля: процессор читает только по выровненным адресам, а в printf передаётся только один нужный байт.
guest8 31.10.2020 19:50 # −999
foxes 31.10.2020 20:00 # 0
gost 31.10.2020 20:06 # 0
Доступ к объекту с невыровненным адресом — это UB по Стандарту C++. Всё, больше никаких рассуждений не требуется: так писать нельзя.
> Иначе говоря такая архитектура гарантирует начало массива Q выровненную надлежащим образом.
Вовсе нет. Компилятор может (и будет, если решит поэкономить место) поместить Q по невыровненному адресу, а операции доступа скорректировать соответствующим образом. Например:
Здесь q вполне может лежать по нечётному адресу. Тогда чтения a и первых трёх элементов q будут генерировать загрузку четырёх байт по адресу &a; чтения элементов q[3]..q[6] — по адресу &q[3].
foxes 31.10.2020 20:13 # 0
Мы уже 10 раз определили разными способами как его, практически не меняя, сделать не UB.
guest8 31.10.2020 20:15 # −999
foxes 31.10.2020 20:18 # 0
gost 31.10.2020 20:23 # 0
Есть такая очень толстая книжка, называется «Стандарт языка C++».
В этой очень толстой книжке, помимо всего прочего, содержатся требования к коду на C++. Если очень упрощать, то в них содержатся утверждения вида «код корректен, если X. Если Y, то код некорректен».
Так вот, в этой книжке написано (опять же, упрощая), что объект типа T может храниться только адресу, выровненному по границе в alignof(T) байт. Если мы попытаемся как-то запихнуть объект типа T в адрес, не выровненный границе в alignof(T), то наш код станет некорректным по Стандарту — то есть, будет содержать UB.
Во всех этих построениях, как ты мог заметить, отсутствует одна важная вещь: упоминание архитектуры. И это неспроста: фишка в том, что, если Стандарт объявляет, что операция X приводит к неопределённому поведению, то она приводит к неопределённому поведению на любой архитектуре, на любом компиляторе и с любым сочетанием директив компиляции.
Все наши рассуждения в этом топике направлены на то, чтобы объяснить, почему исходная операция (доступ по невыровненному адресу) была объявлена Стандартом UB, только и всего.
foxes 31.10.2020 20:33 # 0
guest8 31.10.2020 21:22 # −999
guest8 31.10.2020 21:35 # −999
j123123 31.10.2020 21:54 # +1
foxes 31.10.2020 22:06 # 0
Вот именно вот это "то мы в жопе.". Неопределенный результат всегда трактуется в пользу архитектуры. Иначе говоря определяется архитектурой. Тоже самое когда встал вопрос про "выкинуть UB или все таки добавить выравнивание".
gost 31.10.2020 22:10 # 0
Нет. Ты путаешь неопределённое поведение и поведение, определяемое имплементацией («Implementation-defined behaviour»).
guest8 31.10.2020 22:16 # −999
guest8 31.10.2020 22:10 # −999
foxes 31.10.2020 22:18 # 0
Ну и причем тут компилятор?
"Но я рад, что вы признали наличие тут "неопределенного результата", ведь это и есть UB!"
unspecified переводиться как неопределенный - только и всего.
Точно также как при сдвиге чисел со знаком пишут, что результат не определен - хотя это совсем не так. Все прекрасно определяется архитектурой.
guest8 31.10.2020 22:20 # −999
foxes 31.10.2020 22:27 # 0
Не может такого быть, на примере x86. Потому что указатель на p_body однозначно передается на выход new без какого либо преобразования.
guest8 31.10.2020 22:30 # −999
bormand 31.10.2020 22:21 # +1
Это так, к сожалению. Компилятор на 146% уверен, что сдвиг знакового числа влево не меняет его знак. И если дальше есть какие-то ассёрты или условия про знак числа - он их тупо выбросит. В итоге у тебя потом отрицательное число попадёт в ветку для положительных.
gost 31.10.2020 22:27 # 0
§ 7.6.7
bormand 31.10.2020 23:13 # 0
Блин, а когда пофиксили кста? Я вот смотрю, в a * = 2 и a += a переполнение конпелятор считает UB'ом. А с a <<= 1 аккуратно перепроверяет все инварианты после сдвига, наебать не получается.
gost 31.10.2020 23:14 # 0
bormand 31.10.2020 23:15 # 0
foxes 31.10.2020 22:30 # 0
bormand 31.10.2020 22:33 # +2
Скажем так, он не будет заморачиваться чтобы код работал в кейсах, которые он считает некорректными.
Вот пример: https://ideone.com/EFGoBi
Он не про сдвиг, но вполне показывает чем заканчивается undefined behavior. Там вон куча проверок на отрицательность и на вылет символа за границу. И все они ушли на помойку.
gost 31.10.2020 22:44 # +2
Две проверки выкинул!
defecate-plusplus 31.10.2020 23:10 # 0
Типа тут могло бы быть переполнение, но нахуй его?
gost 31.10.2020 23:13 # 0
gost 31.10.2020 23:16 # +1
UPD: Это ж какой потенциал для наёба автотестов!
gost 31.10.2020 23:10 # +1
https://gcc.godbolt.org/z/TEe4sa
bormand 31.10.2020 23:20 # 0
gost 31.10.2020 23:32 # +1
guest8 31.10.2020 22:33 # −999
bormand 31.10.2020 22:37 # 0
Есть. Команды для знакового сдвига (вправо) отличаются от беззнаковых.
guest8 31.10.2020 22:40 # −999
foxes 31.10.2020 22:52 # 0
guest8 31.10.2020 22:54 # −999
foxes 31.10.2020 22:58 # 0
bormand 31.10.2020 22:43 # 0
gost 31.10.2020 22:25 # 0
Нельзя сдвигать на отрицательное число бит или на число бит, большее, чем размер левого операнда. Всё остальное современный Стандарт разрешает.
> Все прекрасно определяется архитектурой.
И ты опять ничего не понял. В «C++» нет никакой архитектуры, есть только Стандарт. Можно писать код, соответствующий Стандарту — это будет хороший, переносимый код. А можно писать код с UB — и тогда это в самом лучшем случае будет жёстко прибитое к конкретной версии компилятора говно. За такое полагается пинок линейкой из профессии.
foxes 31.10.2020 22:34 # 0
Ты опять в очередной раз не может правильно прочитать предложение, и пытаешься на основе этого мне что то заново объяснить. Или ты просто так самоутверждаешься?
gost 31.10.2020 22:40 # 0
foxes 31.10.2020 22:45 # 0
gost 31.10.2020 22:47 # 0
bormand 31.10.2020 22:16 # +1
Не неопределённый результат, а неопределённое поведение. Иногда из-за UB'а вообще огромный кусок кода пропадает т.к. конпелятор не видит в нём смысла. А иногда начинается пиздец в духе поехавшей логики когда true && true == false.
guest8 31.10.2020 22:22 # −999
foxes 01.11.2020 22:02 # 0
class foo
{
char a __attribute__ ((packed));
int y __attribute__ ((packed));
};
foo array[100] __attribute__ ((aligned (1)));
gost 01.11.2020 22:04 # 0
guest8 02.11.2020 02:56 # −999
foxes 01.11.2020 22:00 # 0
Тоже самое можно легко провернуть для инта.
gost 31.10.2020 19:00 # 0
j123123 31.10.2020 17:01 # +3
Я пробегусь автозаменой, или напишу говноскрипт какой-нибудь (с огрызком парсера), который это сделает только там, где надо
gost 31.10.2020 17:03 # 0
guest8 31.10.2020 15:25 # −999
guest8 31.10.2020 15:26 # −999
bormand 31.10.2020 15:27 # 0
foxes 31.10.2020 15:29 # +1
static int kok2 = petuh(); // выполняется при инициализации.
CHayT 31.10.2020 15:50 # +1
[1] https://gcode.space#!/
j123123 09.11.2020 11:04 # 0
Ваши крестопроблемы с порядком инициализации лишь забавляют меня.
gost 09.11.2020 13:14 # 0
bormand 09.11.2020 13:23 # 0
MAPTbIwKA 09.11.2020 15:07 # 0
foxes 10.03.2016 18:26 # +1
bormand 09.03.2016 20:34 # +1
Или конпелятор просто выбросит этот код, т.к. UB...
kurwa 10.03.2016 01:09 # −1
Круто?
Soul_re@ver 10.03.2016 02:10 # +4
kurwa 10.03.2016 09:51 # 0
kegdan 10.03.2016 09:53 # +3
Antervis 10.03.2016 07:53 # 0
kurwa 10.03.2016 09:48 # 0
Antervis 10.03.2016 10:44 # 0
kurwa 10.03.2016 10:53 # 0
roman-kashitsyn 10.03.2016 10:58 # 0
Деструктор обычно делает что-то важное.
Antervis 10.03.2016 11:01 # +3
roman-kashitsyn 11.03.2016 14:26 # 0
деструктор иногда что-то делает
Antervis 10.03.2016 11:27 # 0
kurwa 10.03.2016 20:30 # 0
bormand 10.03.2016 20:33 # +3
> программы
Чтоб тебе всю жизнь динамически загружаемые модули писать...
bormand 10.03.2016 21:07 # +2
Я бы не был так категоричен. К сожалению, есть ресурсы, с которыми только ребут поможет, если забудешь их освободить... Ну и есть ресурсы, которые ломаются к хуям, если их не освободить и завершить прогу. Примеров не будет, подумай над ними сам.
Antervis 11.03.2016 12:56 # 0
думаешь, ты кому-то тут глаза открыл? Едва ли. Но ресурсами бывает не только память.
> О том, как пофлашить свои данные при завершении, читайте в комментарии немного выше.
> Синхронизировать можно в деструкторе статической переменной-обертки.
Ну да, я же конфетная фабрика, чтобы для каждого куска делать обертку.
И, последнее. Чем твой синглтон лучше чем
kurwa 11.03.2016 23:05 # 0
guest8 31.10.2020 16:35 # −999
foxes 10.03.2016 18:19 # 0
Vasiliy 10.03.2016 18:25 # −1
https://habrahabr.ru/post/147373/
foxes 10.03.2016 18:32 # 0
Vasiliy 10.03.2016 18:46 # 0
foxes 10.03.2016 18:51 # 0
Vasiliy 10.03.2016 19:30 # 0
foxes 10.03.2016 20:13 # −2
Vasiliy 11.03.2016 14:19 # 0
а на хуя тогда пиздеть?
foxes 11.03.2016 14:23 # 0
defecate-plusplus 10.03.2016 20:08 # +4
- Да, здравствуйте, Александр Константинович
foxes 10.03.2016 20:13 # 0
http://govnokod.ru/19596#comment315551
foxes 10.03.2016 20:22 # 0
defecate-plusplus 10.03.2016 20:38 # +2
купите платный аккаунт
kegdan 10.03.2016 21:00 # 0
Vasiliy 11.03.2016 14:20 # 0
guest 11.03.2016 17:42 # 0
Soul_re@ver 11.03.2016 18:01 # +2
guest 11.03.2016 18:07 # 0
3_14dar 11.03.2016 17:45 # +1
1024-- 11.03.2016 19:40 # +1
3_14dar 11.03.2016 19:44 # 0
nihau 11.03.2016 20:44 # 0
1024-- 11.03.2016 21:01 # 0
[NSFW!] http://img0.joyreactor.cc/pics/comment/geek-велосипед-вело-гифки-1767996.gif
kegdan 11.03.2016 21:04 # 0
MAPTOBCKuu_nemyx 30.04.2024 06:39 # 0
1024-- 10.03.2016 20:23 # 0
> Пока я этот код для ржачки не с ляпал
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
foxes 10.03.2016 20:26 # 0
http://govnokod.ru/19596#comment315551
http://govnokod.ru/19596#comment315549
foxes 10.03.2016 20:30 # 0
foxes 10.03.2016 20:38 # 0
1024-- 10.03.2016 20:39 # 0
Очень хорошо, загружайте код, посмеёмся вместе.
> ржать над кодом или над моими рассуждениями
Ммм... Ну код виден; видны и рассуждения. Ржать над кодом - значит ржать над некоторыми поверхностными рассуждениями.
> можно поржать над половиной комментариев
Так затем и собираемся здесь. Давайте ржать уже!
foxes 10.03.2016 20:43 # 0
давай теперь ржать над этим вместе http://govnokod.ru/19596#comment315399
-Eugene- 10.03.2016 20:56 # 0
foxes 10.03.2016 21:06 # +1
-Eugene- 10.03.2016 21:09 # 0
foxes 10.03.2016 21:11 # +1
этот комент http://govnokod.ru/19596#comment315399 и не подписал - во смотрите че пишет, во ржачь.
В принципе все понятно - у колобка нет шеи, и над тем кто так шутит можно по ржать.
bormand 10.03.2016 21:13 # +5
foxes 10.03.2016 21:16 # 0
foxes 10.03.2016 21:31 # 0
guest 10.03.2016 23:03 # 0
foxes 11.03.2016 12:57 # +2
foxes 11.03.2016 14:30 # +2