🦖 Айти Тудэй 🦥
8.55K subscribers
14.9K photos
793 videos
18 files
2.01K links
Авторский бутик айти мемов и не только
Всё самое полезное по тэгу #деградироватьпришёл

Разбан https://t.me/ithueti/18131

Футболочки и чат для своих http://ithueti.club

Реклама: http://ithueti.club/ad / https://telega.in/c/ithueti
Download Telegram
В современном С++ мы можем писать например так:
std::for_each(threads.begin(), threads.end(), std::mem_fun_ref(&std::thread::join));

Это очень круто, мы пишем в близком к функциональному подходу стиле и читается это как настоящий язык: для каждого потока от начала до конца вызови функцию по ссылке - соединиться.

Обычно так и я пишу свой код на работе.

А можем написать вот так, мерко, противно, императивно:
for(auto& t: threads)
t.join();

Так я пишу свой код на работе после того как удалил тот, что написал сначала.
Воистину, только это привилегированное большинство имеет право писать на php в 2019
Forwarded from Hermitage
RPCS3, эмулятор PlayStation 3 под PC (Windows/Linux), здорово развивается — удалось запустить эксклюзивный консольный тайтл Metal Gear Solid 4. Игра функционально в рабочем состоянии, но остались графические баги и артефакты. Есть надежда, что это решаемые баги эмуляции GPU и в ближайшее время они будут устранены. Забавно, но эмулятор уже позволяет снять ограничение в 30fps и играть на 60fps.
Forwarded from oleg_log (Oleg Kovalov)
https://twitter.com/ericniebler/status/1167172402184216576

Эрик Ниблер жарит ваще адовые библиотеки, аж время компиляции отклеивается.

Для этого примера это 4.5 секунды с использованием clang.
Я сейчас в шоке, но уже почти отошел.

Выяснилось, что все это время в С++ можно было так
#include <iostream>
int main() {
size_t size;
std::cin >> size;
int array[size];
}

Т.е. создавать массив динамического размера на стеке! Вот так просто! А я к ЕГЭ готовился и new/delete осваивал, чтобы задачки закодить как надо.

Чуть легче мне стало, когда мне сказали, что все-таки это не по стандарту.

Я перебрал кучу компиляторов и версий языка - можно! Только clang 3.2 сдался, а g++ ниже 4.1.2 не нашел.

А потом я добрался до msvc и увидел заветное
error C2131: expression did not evaluate to a constant

Я до 2018 года только msvc пользовался и знать не знал какая жуть может происходить. Мне нужно выпить.
Сегодня задачка по С++, вопрос простой - что не так? Если хочется подумать самостоятельно, то сначала прочитайте код, высказывайтесь в комментариях, а потом читайте дальше.
#include <iostream>
#include <memory>
#include <thread>

class Base{
public:
virtual ~Base() {
thread.join();
}

void proc() {
thread = std::thread(&Base::foo, this);
}

virtual void foo() {
std::cout << bar() << std::endl;
}

virtual std::string bar() = 0;

std::thread thread;
};

class Child : public Base
{
public:
std::string bar() override { return "Child"; }
};

class Derived : public Base
{
public:
std::string bar() override { return "Derived"; }
};

int main()
{
auto c = std::make_unique<Child>();
auto d = std::make_unique<Derived>();
c->proc();
d->proc();
}

Собираем g++ -O3 -pthread main.cpp и программа падает на вызове чисто виртуальной функции. Наша редакция прибегла к помощи специалистов и путем нехитрых манипуляций внесла изменения в код
virtual std::string bar() { return "Base"; };

Теперь вывод, казалось бы, должен быть очевиден, но нет:
Derived
Base

Перебрав несколько компиляторов и окружений, все таки стало понятно, что бывает и ожидаемый вариант
Base
Base


И я интересуюсь: "Где мое позднее связывание, ̶Л̶е̶б̶о̶в̶с̶к̶и̶ ?"
На что получаю резонное замечание от привлеченных специалистов из крупных международных компаний: "А, собственно, почему оно должно работать? Ты в деструкторе по факту вызываешь виртуальную функцию, наследник уже мертв в этот момент".

class Base{
public:
virtual ~Base() = default;
void wait() { thread.join(); }
...
};

class Child : public Base
{
public:
~Child() { wait(); }
std::string bar() override { return "Child"; }
};

class Derived : public Base
{
public:
~Derived() { wait(); }
std::string bar() override { return "Derived"; }
};

Т.е. по мере разрушения у объектов менялись таблицы виртуальных функций и иногда одному из них везло, а второму не везло никогда.

Вот такой вот способ выстрелить себе в ногу с двух ̶р̶у̶к̶ потоков.