Пошел он в народ, пошел. Если говорить о личном опыте - то у нас в 2010ых все знакомые именно 3.58 гоняли и друг другу копировали, мне тоже именно ее посоветовали.
Но WOG уж очень забагованный был, вылет на ровном месте во время твоего, или, что еще хуже, хода ИИ - обычное дело. Когда появилась Хота, органично и сбалансированно расширяющая игру и развивающаяся совместно с HD модом - она быстро стала доминировать
В Skype точно было. Причем оно умудрялось распознавать два разных случая - когда тыкают рандомные клавиши, собеседник видел ломающийся карандаш, а при зажатии нескольких - собственно котэ
Компилятор перехитрил сам себя. Итак, что происходит?
Тут-то UB происходит: нельзя читать из неинициализированной переменной. Поскольку недопущение таких вещей в зоне ответственности программиста - компилятор справедливо считает что на входе будет bool с конвенционным значением, и оптимизирует как умеет.
Кстати, кто-нибудь знает, может ли сгенерироваться подобный код функции, если компилятор увидит вместо неинициализированной переменной какое-нибудь memcpy(&x, src, sizeof(x))?
Оу, извините, все равно непонятно, почему же получается проще прикрутить к телефону второй модем, а не добраться до встроенного :'(
Правильно ли я понимаю, что по сути проблема в том, что для всей звуковой системы телефона просто нужны заковыристые драйвера, которые по-быстрому не написать и в опенсорсе не доступны, или есть какие-то более фундаментальные трудности?
Извиняюсь, если вопросы глупые, я во внутренностях линухов (и особенно телефонов на нем) не силен, но тема чертовски интересная!
Это и для реальных экранов нормально, ведь экран загрузки обычно показывает прогресс по некоей конкретной, заданной разработчиками, очереди задач, а после ее окончания может проделываться еще какая-то тяжелая работа в главном потоке, из-за которого собственно все и подвисает.
Но, в отличие от поддельного, тут есть два преимущества: время подвисания более-менее фиксированное и зависит обычно только от производительности девайса, а еще это можно зарефакторить и таки сделать по-человечески =)
Довродилось ковыряться в системе загрузочных задач движка одной мобильной игры, так вот у нас все было относительно честно: общий прогресс определяется количеством запланированных и завершенных задач, а так же локальным прогрессом самих задач. Те таски, которые могли (и хотели) точно сообщать о своих достижениях, сообщали, некоторые мухлевали и выдавали приблизительный результат, некоторые о прогрессе не сообщали и результат бинаризовался.
Но вот в разделе про move - семантику, кмк, упустили самое важное - суть этого нововведения, ограничившись какими-то волшебными примерами "перемещения".
А суть в общем-то проста - это именно семантика, позволяющая писать разный код для работы со временными и "долговременными" объектами, rvalue и lvalue. Именно благодаря знанию о сущности аргумента оператора присваивания или конструктора можно написать гораздо более эффективный код, в случае того же std::vector'а позволяющий просто(* за редкими исключениями наподобие несовместимых аллокаторов) обменять указатели на реальный массив вместо честного поэлементного копирования.
ЕМНИП, в опенсорсных реализациях диспетчеризация действительно реализована без виртуальных функций, но она там такая же динамическая, просто написанная вручную.
А вот в оказавшийся под рукой STL из MSVC я даже заглянул: внутри создается объект, реализующий интерфейс _Func_base, то есть в общем-то ровно как у Вас, только чуть более заковыристо и универсально и со Small buffer optimization.
А еще для повышения привилегий есть отличная утилита командной строки - gsudo . Теперь можно запускать от имени админа только то, что действительно этого требует :)
Ну, кроме сложностей с изучением самих шаблонов у новичков (да и у старичков тоже, будем честны) возникают трудности с чтением простыней ошибок инстанциирования шаблонов. По идее, при широком распространении концептов ошибки станут гораздо понятнее, что тоже должно понизить порог входа...
Похоже, что зависит от степени запущенности проекта.
Повырубав кучу ворнингов заставить компиляться и работать не так уж сложно и долго. А потом да, постепенно эти ворнинги исправлять параллельно с разработкой в течение месяцев. Самое удивительное, что когда потом включаешь обратно эти трактуемые как ошибки предупреждения, оказывается, что они вообще-то были очень даже по делу, и фактически работа проводилась вовсе не ради галочки, а сделала продукт стабильнее и лучше.
Другими словами, при переходе на новый стандарт основные проблемы, кмк, возникают именно из-за более чувствительных к ошибкам и нарушению стандарта компиляторов, а отнюдь не прихоти.
Тяжелее всего должен быть переход C++98 на 11, поскольку в древнем C++ очень многие вещи делались абы как и с явным уб, без которого жить было невозможно в принципе(те же потоки)
Рискну предположить, что застряли не в embedded (где вполне можно писать так же, причем еще и практически zero-cost, так как операции над рейнджами очень хорошо инлайнятся и оптимизируются как по производительности, так и размеру исполняемого кода, то, в чем C++ реально хорош и почему все готовы терпеть медленную компиляцию), а в процедурном подходе и старой версии стандарта.
Современный подход, причем не только в C++, а почти во всех языках, подразумевает больший упор в функциональную парадигму: неизменяемые значения, широкое использование функций (в том числе анонимных), в частности в качестве аргументов и возвращаемых значений, отсутствие глобального состояния и декларативность. Привыкнув к этому, можно писать гораздо более надежные и читаемые программы как для микроконтроллеров, так и суперкомпьютеров.
Мультипарадигменный, как и большинство современных языков. Да, в идиоматическом C++ писать в чисто ООП стиле не принято и не особо-то эффективно, но формально C++ вполне себе ООП, равно как и процедурный, структурный, функциональный язык.
Проблема в том, что, когда раньше программист "решал использовать UB", он точно так же отстреливал ноги в промышленных масштабах, причем думая, что знает, что делает.
Создатели компиляторов ничего не считают, и уж тем более не действуют на зло программистам, а просто буквально следуют стандарту. UB - это логическая ошибка, отсутствие ограничения, делающее программу неоднозначной. То, что можно заметить при анализе на уровне компилятора - замечают, и выдают предупреждения. То, что нельзя - остается в программе миной замедленного действия.
Компиляторы же считают, что UB нет, не из-за какой-то особой вредности и обозленности их разработчиков на мир, а потому, что это допущение - естественный способ нормально скомпилировать программу, не пытаясь доказывать математические теоремы произвольной сложности. При допущении, что UB есть, компилятор превращается в совершенно другой продукт - статический анализатор кода, систему, разрабатываемую не менее талантливыми коллективами разработчиков, и по-прежнему имеющую ложно-положительные и ложно-отрицательные результаты.
Средства есть, но не на уровне языка, а на уровне отдельных и самостоятельных утилит, по сложности иногда вполне соразмерных с компилятором и занимающимися совсем другими задачами.
Это санитайзеры (ака динамические анализаторы), статические анализаторы, системы тестирования и т.д.
Спасибо за комментарий, намеренно искал, написал ли кто-то уже об этом.
И кмк это ведь как раз одно из важнейших нововведений C++14, оказавшее огромное влияние на написание кода.
Здорово, конечно, но давно же существует gsudo, которая делает все то, что обещают Майкрософтовцы.
Авторам оригинальной тулзы, наверное, щас обидно было...
Пошел он в народ, пошел. Если говорить о личном опыте - то у нас в 2010ых все знакомые именно 3.58 гоняли и друг другу копировали, мне тоже именно ее посоветовали.
Но WOG уж очень забагованный был, вылет на ровном месте во время твоего, или, что еще хуже, хода ИИ - обычное дело. Когда появилась Хота, органично и сбалансированно расширяющая игру и развивающаяся совместно с HD модом - она быстро стала доминировать
а лично мне Виста понравилась сразу с момента выхода, даже больше чем 7
В Skype точно было. Причем оно умудрялось распознавать два разных случая - когда тыкают рандомные клавиши, собеседник видел ломающийся карандаш, а при зажатии нескольких - собственно котэ
Вот, например, FAQ из хорошего канала в Telegram:
https://github.com/JoshuaJakowlew/cppfaq
Тут-то UB происходит: нельзя читать из неинициализированной переменной. Поскольку недопущение таких вещей в зоне ответственности программиста - компилятор справедливо считает что на входе будет bool с конвенционным значением, и оптимизирует как умеет.
Кстати, кто-нибудь знает, может ли сгенерироваться подобный код функции, если компилятор увидит вместо неинициализированной переменной какое-нибудь
memcpy(&x, src, sizeof(x))
?Оу, извините, все равно непонятно, почему же получается проще прикрутить к телефону второй модем, а не добраться до встроенного :'(
Правильно ли я понимаю, что по сути проблема в том, что для всей звуковой системы телефона просто нужны заковыристые драйвера, которые по-быстрому не написать и в опенсорсе не доступны, или есть какие-то более фундаментальные трудности?
Извиняюсь, если вопросы глупые, я во внутренностях линухов (и особенно телефонов на нем) не силен, но тема чертовски интересная!
Это и для реальных экранов нормально, ведь экран загрузки обычно показывает прогресс по некоей конкретной, заданной разработчиками, очереди задач, а после ее окончания может проделываться еще какая-то тяжелая работа в главном потоке, из-за которого собственно все и подвисает.
Но, в отличие от поддельного, тут есть два преимущества: время подвисания более-менее фиксированное и зависит обычно только от производительности девайса, а еще это можно зарефакторить и таки сделать по-человечески =)
Довродилось ковыряться в системе загрузочных задач движка одной мобильной игры, так вот у нас все было относительно честно: общий прогресс определяется количеством запланированных и завершенных задач, а так же локальным прогрессом самих задач. Те таски, которые могли (и хотели) точно сообщать о своих достижениях, сообщали, некоторые мухлевали и выдавали приблизительный результат, некоторые о прогрессе не сообщали и результат бинаризовался.
Спасибо за статью!
Больше C++, хорошего и разного.
Но вот в разделе про move - семантику, кмк, упустили самое важное - суть этого нововведения, ограничившись какими-то волшебными примерами "перемещения".
А суть в общем-то проста - это именно семантика, позволяющая писать разный код для работы со временными и "долговременными" объектами, rvalue и lvalue. Именно благодаря знанию о сущности аргумента оператора присваивания или конструктора можно написать гораздо более эффективный код, в случае того же
std::vector
'а позволяющий просто(* за редкими исключениями наподобие несовместимых аллокаторов) обменять указатели на реальный массив вместо честного поэлементного копирования.Все примерно так и есть.
ЕМНИП, в опенсорсных реализациях диспетчеризация действительно реализована без виртуальных функций, но она там такая же динамическая, просто написанная вручную.
А вот в оказавшийся под рукой STL из MSVC я даже заглянул: внутри создается объект, реализующий интерфейс _Func_base, то есть в общем-то ровно как у Вас, только чуть более заковыристо и универсально и со Small buffer optimization.
А еще для повышения привилегий есть отличная утилита командной строки - gsudo . Теперь можно запускать от имени админа только то, что действительно этого требует :)
Ну, кроме сложностей с изучением самих шаблонов у новичков (да и у старичков тоже, будем честны) возникают трудности с чтением простыней ошибок инстанциирования шаблонов. По идее, при широком распространении концептов ошибки станут гораздо понятнее, что тоже должно понизить порог входа...
Если Вам из деструкторов нужно кидать исключения, то у меня очень плохие новости об архитектуре проекта, который Вы пишете...
Похоже, что зависит от степени запущенности проекта.
Повырубав кучу ворнингов заставить компиляться и работать не так уж сложно и долго. А потом да, постепенно эти ворнинги исправлять параллельно с разработкой в течение месяцев. Самое удивительное, что когда потом включаешь обратно эти трактуемые как ошибки предупреждения, оказывается, что они вообще-то были очень даже по делу, и фактически работа проводилась вовсе не ради галочки, а сделала продукт стабильнее и лучше.
Другими словами, при переходе на новый стандарт основные проблемы, кмк, возникают именно из-за более чувствительных к ошибкам и нарушению стандарта компиляторов, а отнюдь не прихоти.
Тяжелее всего должен быть переход C++98 на 11, поскольку в древнем C++ очень многие вещи делались абы как и с явным уб, без которого жить было невозможно в принципе(те же потоки)
Рискну предположить, что застряли не в embedded (где вполне можно писать так же, причем еще и практически zero-cost, так как операции над рейнджами очень хорошо инлайнятся и оптимизируются как по производительности, так и размеру исполняемого кода, то, в чем C++ реально хорош и почему все готовы терпеть медленную компиляцию), а в процедурном подходе и старой версии стандарта.
Современный подход, причем не только в C++, а почти во всех языках, подразумевает больший упор в функциональную парадигму: неизменяемые значения, широкое использование функций (в том числе анонимных), в частности в качестве аргументов и возвращаемых значений, отсутствие глобального состояния и декларативность. Привыкнув к этому, можно писать гораздо более надежные и читаемые программы как для микроконтроллеров, так и суперкомпьютеров.
Мультипарадигменный, как и большинство современных языков. Да, в идиоматическом C++ писать в чисто ООП стиле не принято и не особо-то эффективно, но формально C++ вполне себе ООП, равно как и процедурный, структурный, функциональный язык.
Проблема в том, что, когда раньше программист "решал использовать UB", он точно так же отстреливал ноги в промышленных масштабах, причем думая, что знает, что делает.
Создатели компиляторов ничего не считают, и уж тем более не действуют на зло программистам, а просто буквально следуют стандарту. UB - это логическая ошибка, отсутствие ограничения, делающее программу неоднозначной. То, что можно заметить при анализе на уровне компилятора - замечают, и выдают предупреждения. То, что нельзя - остается в программе миной замедленного действия.
Компиляторы же считают, что UB нет, не из-за какой-то особой вредности и обозленности их разработчиков на мир, а потому, что это допущение - естественный способ нормально скомпилировать программу, не пытаясь доказывать математические теоремы произвольной сложности. При допущении, что UB есть, компилятор превращается в совершенно другой продукт - статический анализатор кода, систему, разрабатываемую не менее талантливыми коллективами разработчиков, и по-прежнему имеющую ложно-положительные и ложно-отрицательные результаты.
Средства есть, но не на уровне языка, а на уровне отдельных и самостоятельных утилит, по сложности иногда вполне соразмерных с компилятором и занимающимися совсем другими задачами.
Это санитайзеры (ака динамические анализаторы), статические анализаторы, системы тестирования и т.д.