Кроме того, погуглил сейчас и сразу наткнулся на статьи А (2011 год)
вы игнорируете ту часть статьи, где говорится "Масштабное бета-тестирование GW — пусть пока только в США, только в сети Sprint и только на смартфонах Nexus S — стартует уже этим летом". То есть статья написана не просто раньше запуска технологии, а раньше старта её бета-теста.
и Б (судя по тексту, 2012 год)
"Сейчас сервис Google Wallet проходит множество тестов и пока не является полностью сформированным, с этим и связаны разные ограничения в использовании: один смартфон, один оператор. Летом корпорация Google заявила, что экспериментальная часть закончена и Wallet готова к эксплуатации. Однако в нынешнем развитии событий всё равно продолжается масштабное тестирование".
Но про наличие возможности платить через NFC таки писали еще в 2011.
Не очень понимаю, почему для вас копирование sizeof<U> > sizeof<T> байт из переменной типа T очевидно не является UB, а каст является.
потому что я исхожу из предположения, что указатель смотрит на valid instance U или что-то layout-compatible с U. В противном случае UB ожидаемо гарантирован и при касте, и при копировании. Но ведь документация говорит не так, она говорит что transmute_copy в тип большего размера это UB независимо от всего остального.
Согласен, что раздел о кастах выглядит не совсем полным, но в списке UB кастов тоже нет, только разыменования.
а еще в списке UB написано что он неполный, и про касты/трансмьюты там ничего нет. Могли бы хоть добавить туда индекс со ссылками на все UB, обозначенные в других разделах.
Да и в многочисленных предупреждениях о незавершённости модели памяти тоже говорится о разыменованиях, а не о самих кастах.
пока модель памяти не завершена, поведение всего, что от неё зависит, не определено, т.е. UB. Ну это так, к слову.
Я ни в коем случае не глорю раст, просто прочитав ту же самую документацию, я в ней вижу совершенно другие утверждения, чем вы.
значит вопрос в том, кто из нас смотрит в документацию и видит в ней то, что там написано, верно?
Ну камон, то что вы цитируете про размеры типов очевидно относится не к касту, а к операции «каст + копирование».
во-первых, transmute_copy это не "каст + копирование", а "копирование + каст", и весьма очевидно что UB кроется в касте, а не в копировании. Во-вторых, там буквально написано что А. transmute_copy'ровать в тип большего размера - UB, и B. это правило распространяется и на касты указателей.
И вот эта фраза никак этого не отменяет.
Она буквально и прямым текстом говорит что касты указателей никаким волшебным образом не обходят правила transmute/transmute_copy. И единственная причина почему все эти UB не перечислены в главе про указатели - она неполная (за незавершенностью модели памяти), сказано лишь что *T всегда должен указывать на valid instance of T, и что нужно придерживаться правил pointer aliasing'а и borrowing'а.
Неужели вы всерьез готовы глорить раст даже вопреки его единственной документации?
Ну всё-таки здесь нет однозначного запрета. И на самом деле в Rust кастить указатели можно любой к любому, а правила разименования того что получилось менее строгие чем в C++.
в rust некорректный каст указателя уже является UB, и это куда более строгий запрет, чем в с++. А потом разыменовывай сколько влезет, ага.
Это был буфер, считайте, для обёрток над интами (у которых тоже бывают лайфтаймы, однако).
мне кажется вы просто разную планку ставите. Когда речь о с++, вы считаете что код работает только если он на 100% соответствует стандарту. А когда речь о других языках, то вас совершенно устраивает поведение, определенное одним конкретным компилятором. Так-то больша́я часть UB в с++ вполне себе well defined в компиляторах.
Этого нет ни в расте, ни в хаскеле, ни, насколько я знаю, во всяких сишарпах-джавах.
а еще в них нельзя делать то, что можно в плюсах.
а в C++ есть проблемы и с этим (вы не можете просто взять кусок памяти и проинтерпретировать его как int, до C++20 — даже если это кусок памяти от malloc(sizeof(int))).
удачи сделать это без UB в rust: "src must point to a properly initialized value of type T" (std::ptr::read_unaligned).
И если уж гулять, то хотелось бы, чтобы места, в которых код может гулять по памяти, были как-то явно выделены и изолированы
это то тут при чем? Вот я утверждаю: есть люди, которые чаще всего нынешние или бывшие сишники, которые чаще пишут под всякую микруху, и которые критикуют с++ за оптимизации на основе UB, которые видите ли ломают им код. Кажется даже здесь где-то были.
Неа, вы потеряли семантику. ... Именно.
ну то есть по итогу не потерял. Правда, не понимаю, чего я добился или чего вы хотели сказать. В каждом языке есть свои хитрые нечитаемые трюки, в с++ их наверно даже меньше чем в условном js.
Подождите. Как мне через плюсовый std::variant выразить рекурсивную структуру данных?
как ObjectInt/ObjectString помогают вам выразить рекурсивную структуру данных? Никак же, просто бойлерплейт.
Касательно всего следующего - здесь я причесал ваш сниппет согласно моим же замечаниям, плюс пара мелочей - забытые &, подчеркнул потенциальный null deref, кое где привел к стилю.
Детальнее тут
Давайте начнем с того, что в плюсах конструкция return ctx.withPayload([&ctx](auto& payload){...})выглядит странно - в объект передается лямбда, захватывающая и использующая этот объект. Обычно бы написали функцию, принимающую ctx аргументом вместе с payload'ом. И вся портянка была бы в этой функции, как-то так.
Во-первых, использование исключений сократит только внешний try/catch, не более.
в качестве абсолютного минимума оно еще убирает hoistNothing, а приведение исключений к результату выносится во внешний catch блок.
Во-вторых, вызывающий код ничего не хочет знать про исключения, вызывающий код хочет получать std::optional<T> и проверять её
А вызывающий код так хочет потому что... ээм... вы взяли пример из реализации на хаскеле, языке, в котором принято возвращать значение типов-сумм/произведений? В с++ то таких ограничений нет. И совершенно нормально если с++ API кидает исключения. Разве что еще приветствуется в дополнение к кидающим версиям делать не кидающие.
А с исключениями у вас есть три варианта:
(три убогих варианта)
4. ловить std::exception& и брать текст ошибки из e.what()?
Да, хаскель версия всё еще короче. Но не настолько короче и не настолько читаемее (если), чтобы говорить о какой-то кардинальной разнице.
Google pay (сначала он звался вроде Android pay) появился не на пустом месте. До него уже был Google wallet, ктторый умел платить через NFC.
google wallet был всего лишь электронным кошельком, своего рода аналогом paypal. Переводить деньги с кошелька на кошелек он мог уметь по любому протоколу, а вот платить банковской картой он не мог. Соответственно функционала оплаты банковской картой по NFC в нём попросту не могло быть.
Впрочем, мне ниже объяснили, что открытие полноценного браузера позволяет дальше браузить сеть, помимо данных виджета, и это какое-никакое продвижение браузера
и предложит сделаться браузером по умолчанию. При этом edge в win11 может стать браузером по умолчанию в один клик, а любой другой браузер - нет.
Здесь: "mem::transmute_copy<T, U> somehow manages to be even more wildly unsafe than this. It copies size_of<U> bytes out of an &T and interprets them as a U. The size check that mem::transmutehas is gone (as it may be valid to copy out a prefix), though it is Undefined Behavior for U to be larger than T".
По умолчанию компилятор такое не пропустит, если вам от этого легче
Беглый гугл подсказал, что это о копировании с помощью mem::transmute_copy<T, U>, не о касте.
Оттуда же: "Also of course you can get all of the functionality of these functions using raw pointer casts or unions, but without any of the lints or other basic sanity checks. Raw pointer casts and unions do not magically avoid the above rules."
те, кто гуляет по UB и бесится что компилятор не дает им работать с памятью как с простым массивом байт точно не являются подмножеством тех, кто хочет рантайм проверку повсюду.
Ну так то было 10-15 лет назад, я тогда ботами ещё не занимался. А в тех ботах, которыми я занимался недавно, вы и unique_ptr не найдёте.
trivial ABI для unique_ptr пробовали?
Просто как медицинский факт — до C++11 люди как-то более-менее код писали относительно успешно
как только мне доводится залазить в с++03 код, обычно одних лишь подсказок IDE достаточно чтобы насчитать с десяток лишних копий в одном файле. Просто критерий "успешности" тоже эволюционировал.
Можете назвать платформу, для которой сейчас нет бустовских/ACE/POCO/етц-тредов и мьютексов, а вот стандартные плюсовые там есть?
ну на винде нет толкового posix, а всё остальное не всегда хочется тащить в проект.
Сколько времени вам (и прочим, всё ещё читающим тред) понадобится, чтобы распарсить, что здесь происходит? Чур не запускать.
мне понадобилась пара секунд, вероятно потому, что я ожидал такой выпад. Лучше было бы написать так - корректнее и читаемее:
Или хитрая засада была в вычислении задом наперед?
На днях я написал такую функцию:
там весь пример как назло переусложнен. Всякие ObjectInt/ObjectMap и т.д. никто в здравом уме делать не будет, используются using или в худшем случае, если нужен distinct type, делают через наследование. Вместо std::make_tuple тут нужен std::tie. Но это всё мелочи.
Важно то, что вы смешали optional и исключения. Если писать только с исключениями, вообще без optional, код можно очень сильно сократить, а бонусом будет прокидываться текст ошибки из "задачи со звёздочкой".
И сдается мне что если писать только на optional, без исключений, то код тоже может получиться короче, точнее, длиннее, но менее объемным. Грубо говоря, struct Nothing не нужен, все её использования спокойно заменяются на return std::nullopt, а реальное экономие на исключениях у вас всего несколько строк внутри лямбд, что вы в общем-то скомпенсировали hoist'ом.
Конечно же код с optional был бы еще короче будь в с++ монадические интерфейсы, их не хватает, и с этим я согласен.
Ура, тут мы стали C++20-only, потому что до C++20 нельзя капчурить structured bindings в лямбды.
На самом деле, никто не запрещает MS из виджетов переходить на странички, которые корректно работают только в edge.
ну это уже злоупотребление монопольным положением
Например, из-за нестандартных тегов HTML или из-за нестандартных заголовков HTTP
меня как пользователя абсолютно не волнует чего MS хотят добиться этим ходом. Я хочу чтобы мне не навязывали edge. А как "продвинутый пользователь интернетов" я понимаю что кастомные теги html и заголовки http для рендеринга страниц не нужны
и куча клиентов. Да даже если бы и был один клиент, как "для протокола steam:", протокол, который перехватывает MS, всё еще остается открытым и стандартизованным. Если я хочу переопределить браузер, значит, я хочу чтобы ровно ни единая ссылка на свете не могла открыть какой-то другой. А еще больше я хочу чтобы MS больше ловили по шапке за злоупотребление монополией.
А я вот искренне не понимаю, почему это вдруг начало считаться нормальным, что на целый универсальный компьютер ...
понимаете, вот для самоделкиных всё в чем есть чип - "универсальный компьютер", а любимое занятие - запускать doom на фитнес браслетах. И если вам нужен "универсальный компьютер", а не "смартфон", покупайте конечно себе на здоровье хоть андроид, хоть линуксофон, хоть mp3 плееры на барахолках. Но не надо пожалуйста утверждать что желания единиц таких вот самоделкиных должны формировать общее направление развития индустрии. Потому что любой, кто был в ситуации "я у мамы первая линия техподдержки" прекрасно знает, что иногда настроек бывает чересчур много, и что для подавляющего большинства пользователей надежность в приоритете над кастомизацией. Причем на практике эти вещи противоречат друг другу.
Первым Android смартфоном с поддержкой NFC стал Samsung Nexus S, который вышел в 2010 году. В iPhone технологию добавили только в iPhone 6, в 2014 году, хотя фанаты ждали NFC в iPhone 5. Но и то поначалу лишь для поддержки собственной мобильной системы Apple Pay.
google pay, однако, появился на год позже apple pay. Т.е. да, NFC в андроиде был, но использовался разве что как более быстрый блютуз для передачи данных.
Темная тема начала набирать популярность в 2017 году. И в 2018-м уже появилась в Android 9 Pie. А чуть меньше, чем через год похожей фишкой вдруг обзавелась iOS 13.
Системная темная тема появилась в android 10. Apple здесь были пионером. "Системная" в том смысле, что пользовательские приложения тоже знали какая тема должна использоваться.
Вообще если сравнивать нововведения свежих версий android и ios, видно, что и там и там примерно по половине нововведений есть в конкуренте. Правда, иногда фичи дебютируют в прошивках одного из вендоров, появляясь в самом андроиде годами позже.
вот именно что не видите. Ссылки, открывающие teams, zoom, и т.д. могут быть назначены на альтернативные клиенты. А эти ссылки не переназначаются. Представьте, что завтра гугл сервисы перейдут на ссылки chrome://blablabla, и вы не сможете пользоваться ими из других браузеров?
Нет, не требует. И код, нарушающий panic safety, является sound
то есть через нарушение panic safety можно допустить UB в safe rust?
Да нет, не зависит. Но если вы можете привести конкретный пример, мне было бы интересно.
Например отсюда есть пара ссылок на доку LLVM, namely "pointer aliasing rules" и "uninitialized memory".
А вообще если судить по списку потенциальных UB transmute, кажется основной принцип UB в раст таков, что правила сильно строже, для простоты. Взять например правило что каст & в &mut это UB, в отличие от плюсов, где UB - модификация const объекта, а кастить туда-обратно можно сколько влезет. Впрочем, раст запрещает "mutating immutable data" отдельно. Или например для структуры struct S { int x, y; } c++ позволит сделать каст S* -> int* -> S* без UB (т.к. первый член S - int), в то время как в rust второй каст будет UB, ведь "it is Undefined Behavior for U to be larger than T".
MS далеко до такого болтоположения на мнение юзера!
давайте начнем хотя бы с того, что установка яндекс-браузера дело добровольное (пусть и иногда случайное), так же как и его удаление. MS не просто не спрашивает, хотите ли вы вообще иметь их браузер установленным (что кстати кое-где уже признано монопольными практиками), так еще и шаг за шагом вынуждает использовать именно его.
ну у вендоров сейчас два пути: либо пойти путём apple, потратить лет 10 и миллиарды долларов на R&D и в конце концов возможно представить достойный чип, либо жрать что дает ARM и мириться с их изъянами. Эволюционное развитие второго пути - добавить к ARM ядрам свой ускоритель чего-нибудь и продавать как киллер фичу нового чипа.
не вики, а вы
вы игнорируете ту часть статьи, где говорится "Масштабное бета-тестирование GW — пусть пока только в США, только в сети Sprint и только на смартфонах Nexus S — стартует уже этим летом". То есть статья написана не просто раньше запуска технологии, а раньше старта её бета-теста.
"Сейчас сервис Google Wallet проходит множество тестов и пока не является полностью сформированным, с этим и связаны разные ограничения в использовании: один смартфон, один оператор. Летом корпорация Google заявила, что экспериментальная часть закончена и Wallet готова к эксплуатации. Однако в нынешнем развитии событий всё равно продолжается масштабное тестирование".
про теоретическую возможность то?
потому что я исхожу из предположения, что указатель смотрит на valid instance U или что-то layout-compatible с U. В противном случае UB ожидаемо гарантирован и при касте, и при копировании. Но ведь документация говорит не так, она говорит что transmute_copy в тип большего размера это UB независимо от всего остального.
а еще в списке UB написано что он неполный, и про касты/трансмьюты там ничего нет. Могли бы хоть добавить туда индекс со ссылками на все UB, обозначенные в других разделах.
пока модель памяти не завершена, поведение всего, что от неё зависит, не определено, т.е. UB. Ну это так, к слову.
значит вопрос в том, кто из нас смотрит в документацию и видит в ней то, что там написано, верно?
"терпеть не могу эксклюзивы" подумал я и продолжил играть в spider-man на ps4...
во-первых, transmute_copy это не "каст + копирование", а "копирование + каст", и весьма очевидно что UB кроется в касте, а не в копировании. Во-вторых, там буквально написано что А. transmute_copy'ровать в тип большего размера - UB, и B. это правило распространяется и на касты указателей.
Она буквально и прямым текстом говорит что касты указателей никаким волшебным образом не обходят правила transmute/transmute_copy. И единственная причина почему все эти UB не перечислены в главе про указатели - она неполная (за незавершенностью модели памяти), сказано лишь что *T всегда должен указывать на valid instance of T, и что нужно придерживаться правил pointer aliasing'а и borrowing'а.
Неужели вы всерьез готовы глорить раст даже вопреки его единственной документации?
в rust некорректный каст указателя уже является UB, и это куда более строгий запрет, чем в с++. А потом разыменовывай сколько влезет, ага.
мне кажется вы просто разную планку ставите. Когда речь о с++, вы считаете что код работает только если он на 100% соответствует стандарту. А когда речь о других языках, то вас совершенно устраивает поведение, определенное одним конкретным компилятором. Так-то больша́я часть UB в с++ вполне себе well defined в компиляторах.
а еще в них нельзя делать то, что можно в плюсах.
удачи сделать это без UB в rust: "
srcmust point to a properly initialized value of typeT" (std::ptr::read_unaligned).это то тут при чем? Вот я утверждаю: есть люди, которые чаще всего нынешние или бывшие сишники, которые чаще пишут под всякую микруху, и которые критикуют с++ за оптимизации на основе UB, которые видите ли ломают им код. Кажется даже здесь где-то были.
ну то есть по итогу не потерял. Правда, не понимаю, чего я добился или чего вы хотели сказать. В каждом языке есть свои хитрые нечитаемые трюки, в с++ их наверно даже меньше чем в условном js.
как ObjectInt/ObjectString помогают вам выразить рекурсивную структуру данных? Никак же, просто бойлерплейт.
Касательно всего следующего - здесь я причесал ваш сниппет согласно моим же замечаниям, плюс пара мелочей - забытые &, подчеркнул потенциальный null deref, кое где привел к стилю.
Детальнее тут
Давайте начнем с того, что в плюсах конструкция
return ctx.withPayload([&ctx](auto& payload){...})выглядит странно - в объект передается лямбда, захватывающая и использующая этот объект. Обычно бы написали функцию, принимающую ctx аргументом вместе с payload'ом. И вся портянка была бы в этой функции, как-то так.в качестве абсолютного минимума оно еще убирает hoistNothing, а приведение исключений к результату выносится во внешний catch блок.
А вызывающий код так хочет потому что... ээм... вы взяли пример из реализации на хаскеле, языке, в котором принято возвращать значение типов-сумм/произведений? В с++ то таких ограничений нет. И совершенно нормально если с++ API кидает исключения. Разве что еще приветствуется в дополнение к кидающим версиям делать не кидающие.
4. ловить
std::exception&и брать текст ошибки изe.what()?Да, хаскель версия всё еще короче. Но не настолько короче и не настолько читаемее (если), чтобы говорить о какой-то кардинальной разнице.
google wallet был всего лишь электронным кошельком, своего рода аналогом paypal. Переводить деньги с кошелька на кошелек он мог уметь по любому протоколу, а вот платить банковской картой он не мог. Соответственно функционала оплаты банковской картой по NFC в нём попросту не могло быть.
и предложит сделаться браузером по умолчанию. При этом edge в win11 может стать браузером по умолчанию в один клик, а любой другой браузер - нет.
Здесь: "
mem::transmute_copy<T, U>somehow manages to be even more wildly unsafe than this. It copiessize_of<U>bytes out of an&Tand interprets them as aU. The size check thatmem::transmutehas is gone (as it may be valid to copy out a prefix), though it is Undefined Behavior forUto be larger thanT".По умолчанию компилятор такое не пропустит, если вам от этого легче
Оттуда же: "Also of course you can get all of the functionality of these functions using raw pointer casts or
unions, but without any of the lints or other basic sanity checks. Raw pointer casts andunions do not magically avoid the above rules."те, кто гуляет по UB и бесится что компилятор не дает им работать с памятью как с простым массивом байт точно не являются подмножеством тех, кто хочет рантайм проверку повсюду.
trivial ABI для unique_ptr пробовали?
как только мне доводится залазить в с++03 код, обычно одних лишь подсказок IDE достаточно чтобы насчитать с десяток лишних копий в одном файле. Просто критерий "успешности" тоже эволюционировал.
ну на винде нет толкового posix, а всё остальное не всегда хочется тащить в проект.
мне понадобилась пара секунд, вероятно потому, что я ожидал такой выпад. Лучше было бы написать так - корректнее и читаемее:
Или хитрая засада была в вычислении задом наперед?
там весь пример как назло переусложнен. Всякие ObjectInt/ObjectMap и т.д. никто в здравом уме делать не будет, используются using или в худшем случае, если нужен distinct type, делают через наследование. Вместо
std::make_tupleтут нуженstd::tie. Но это всё мелочи.Важно то, что вы смешали optional и исключения. Если писать только с исключениями, вообще без optional, код можно очень сильно сократить, а бонусом будет прокидываться текст ошибки из "задачи со звёздочкой".
И сдается мне что если писать только на optional, без исключений, то код тоже может получиться короче, точнее, длиннее, но менее объемным. Грубо говоря,
struct Nothingне нужен, все её использования спокойно заменяются на returnstd::nullopt, а реальное экономие на исключениях у вас всего несколько строк внутри лямбд, что вы в общем-то скомпенсировали hoist'ом.Конечно же код с optional был бы еще короче будь в с++ монадические интерфейсы, их не хватает, и с этим я согласен.
можно, через [&foo=foo]. Согласен, хак.
ну это уже злоупотребление монопольным положением
меня как пользователя абсолютно не волнует чего MS хотят добиться этим ходом. Я хочу чтобы мне не навязывали edge. А как "продвинутый пользователь интернетов" я понимаю что кастомные теги html и заголовки http для рендеринга страниц не нужны
и куча клиентов. Да даже если бы и был один клиент, как "для протокола steam:", протокол, который перехватывает MS, всё еще остается открытым и стандартизованным. Если я хочу переопределить браузер, значит, я хочу чтобы ровно ни единая ссылка на свете не могла открыть какой-то другой. А еще больше я хочу чтобы MS больше ловили по шапке за злоупотребление монополией.
в ваших реалиях
понимаете, вот для самоделкиных всё в чем есть чип - "универсальный компьютер", а любимое занятие - запускать doom на фитнес браслетах. И если вам нужен "универсальный компьютер", а не "смартфон", покупайте конечно себе на здоровье хоть андроид, хоть линуксофон, хоть mp3 плееры на барахолках. Но не надо пожалуйста утверждать что желания единиц таких вот самоделкиных должны формировать общее направление развития индустрии. Потому что любой, кто был в ситуации "я у мамы первая линия техподдержки" прекрасно знает, что иногда настроек бывает чересчур много, и что для подавляющего большинства пользователей надежность в приоритете над кастомизацией. Причем на практике эти вещи противоречат друг другу.
google pay, однако, появился на год позже apple pay. Т.е. да, NFC в андроиде был, но использовался разве что как более быстрый блютуз для передачи данных.
Системная темная тема появилась в android 10. Apple здесь были пионером. "Системная" в том смысле, что пользовательские приложения тоже знали какая тема должна использоваться.
Вообще если сравнивать нововведения свежих версий android и ios, видно, что и там и там примерно по половине нововведений есть в конкуренте. Правда, иногда фичи дебютируют в прошивках одного из вендоров, появляясь в самом андроиде годами позже.
вот именно что не видите. Ссылки, открывающие teams, zoom, и т.д. могут быть назначены на альтернативные клиенты. А эти ссылки не переназначаются. Представьте, что завтра гугл сервисы перейдут на ссылки chrome://blablabla, и вы не сможете пользоваться ими из других браузеров?
то есть через нарушение panic safety можно допустить UB в safe rust?
Например отсюда есть пара ссылок на доку LLVM, namely "pointer aliasing rules" и "uninitialized memory".
А вообще если судить по списку потенциальных UB transmute, кажется основной принцип UB в раст таков, что правила сильно строже, для простоты. Взять например правило что каст & в &mut это UB, в отличие от плюсов, где UB - модификация const объекта, а кастить туда-обратно можно сколько влезет. Впрочем, раст запрещает "mutating immutable data" отдельно. Или например для структуры
struct S { int x, y; }c++ позволит сделать каст S* -> int* -> S* без UB (т.к. первый член S - int), в то время как в rust второй каст будет UB, ведь "it is Undefined Behavior for U to be larger than T".давайте начнем хотя бы с того, что установка яндекс-браузера дело добровольное (пусть и иногда случайное), так же как и его удаление. MS не просто не спрашивает, хотите ли вы вообще иметь их браузер установленным (что кстати кое-где уже признано монопольными практиками), так еще и шаг за шагом вынуждает использовать именно его.
ну у вендоров сейчас два пути: либо пойти путём apple, потратить лет 10 и миллиарды долларов на R&D и в конце концов возможно представить достойный чип, либо жрать что дает ARM и мириться с их изъянами. Эволюционное развитие второго пути - добавить к ARM ядрам свой ускоритель чего-нибудь и продавать как киллер фичу нового чипа.
очередной заход на несколько лет злоупотребления пока антимонополисты не расчехлятся их приструнить