Что не даёт на C++ писать кроссплатформенные приложения?

Скажите пожалуйста, что не даёт легко писать кроссплатформенные приложения на C++, изза как следствие их так мало редакций под разные операционные системы, вроде ведь при компиляции линкер добавляет к коду указанный загрузчик, неужели трудно откомпилировать под разные платформы, или код для разных ОС както принципиально друг от друга особым образом отличается?

P.S. в институт не посчастливилось пойти как счастливчикам, по этому приходится спрашивать в интернете (что конечно следовало бы делать там), как все нормальные люди. Может это недостаток подключаемых библиотек, какието API, разные переменные области хранения данных, может конструкции языка не предназначены для этого и всё такое. Или нельзя дать однозначного ответа на этот вопрос и он подлежит немедленному удалению?
  • Вопрос задан
  • 4219 просмотров
Решения вопроса 8
@MarkusD Куратор тега C++
все время мелю чепуху :)
Да, как бы, ничего не мешает писать один С++ код для множества платформ. Почти весь мой трудовой стаж связан именно с разработкой кроссплатформенных игр. Я работал с несколькими (самодельными и не очень) движками и имею свое собственное детище, прекрасно и однозначно собирающееся на 5 целевых платформ (Win, Mac, Linux, ios, Android), к которым без труда можно добавить и консоли, и новые платформы.

Нет, вру, не без труда. Попотеть над слоем абстракции придется. Но попотеть придется только над ним, все остальное заведется само, т.к. изначально написано в стандарте C++, без расширений под конкретные компиляторы, и с применением ряда очень важных для кроссплатформенности подходов.

Кроссплатформенность подразумевает решение ряда вопросов, которые и выливаются в слой абстракции над операционной системой. Эти вопросы, зачастую, решать никто не хочет. Несколько раз встречал такое сам и еще мне рассказывали о том, как тот или иной движок сперва был только под конкретную ###, а потом решили портировать на @@@. Оказалось, что компилятор, которым всегда и собирали движок, нашпигован расширениями языка, которые конечно же все пользовали на 100%, и при смене компилятора ни один файл исходников не остался без доброй сотни ошибок. Т.е. переписывать надо было ВСЁ.

Mercury13 хорошо рассказал про Unicode пути к файлам. Drakonoved правильно подметил про разделители путей к файлам. Максим Гришин очень хорошо напомнил про порядок следования байт. Это все и есть часть этого ряда вопросов.
У каждой платформы есть свой API, которого не будет на другой платформе. Но на другой платформе будет свой API, со своими именами и схожей функциональностью. И работу с API надо абстрагировать от универсального кода.
Еще, на одной платформе у тебя может быть разомкнутый главный цикл обработки сообщений (Win), а на другой - замкнутый (Android). Надо подстраиваться. GUI везде разный, надо подстраиваться. Сама структура приложения на одной платформе может быть монолитной, а на другой - композиционной. Графические и звуковые API могут быть и кроссплатформенными, однако простоты использования это им не прибавляет. Инициализация все равно будет платформозависимой.
На самом деле даже в рамках работы на одной платформе надо соблюдать ряд правил, чтобы иметь возможность из одного кода получать и 32-битное приложение, и 64-битное тоже. Об этом неплохо написано на сайте разработчиков PVS-Studio.

И все это решается. От части - с помощью архитектурных приемов. Один из таких я уже показывал в другом своем ответе.
И еще эти вопросы можно не решать.
ДубльГИС, например, уже давно работает на базе Qt, что сильно упростило им кроссплатформенную жизнь. Qt решает ряд проблем кроссплатформенности.
Ответ написан
saboteur_kiev
@saboteur_kiev Куратор тега C++
software engineer
Любая программа, написанная под конкретную платформу - работает гарантированно на этой платформе.

java считается кроссплатформенной, потому что вы пишете не под линукс и не под виндовс и не под андроид, а под java, а уже те, кто писали саму java машину, берут на себя то, что сперва на windows/linux/android будет установлена соответствующей версии java, в которой будет крутиться ваша программа.
При этом все равно разница существует, поэтому нужно ее учитывать при разработке.

Для С и С++ основная платформа - ОС, а то и непосредственно процессор, следовательно уровень абстракции от железа и архитектуры в этом языке низкий, и для разработки кроссплатформенного софта, учет всех нюансов различных архитектур и операционок будет на программисте.
Ответ написан
Комментировать
Nipheris
@Nipheris Куратор тега C++
  • прикладное API различных операционных систем - разное. Если бы API было полностью одинаковое, то тогда операционные системы отличались бы только UX, набором софта и утилит, т.е. вместо Linux/Windows/BSD мы бы имели только Linux в разных дистрибуциях или только Windows в разных дистрибуциях. Ну т.е. по сути одну операционную систему, т.к. раз мы сейчас говорим о разработке прикладного софта, то нас интересует прежде всего API для прикладных приложений;
  • т.к. API различных ОС отличается, требуется создание уровней абстракции, которые нивелируют эти различия. В других ответах уже достаточно примеров, я бы вспомнил например о разделителях в именах файлов;
  • дополнительные уровни абстракции нередко сокращают доступное API, т.к. в большинстве случаев невозможно реализовать самому то, что нет в API какой-то из интересующих ОС. Следовательно, приходится оставлять только те интерфейсы, которые так или иначе есть везде;
  • т.к. абстрагированные интерфейсы из пред. пункта более аскетичны, ими сложнее пользоваться, они дают не все возможности, соотв. какие-то задачи уже нецелесообразно решать кроссплатформенным кодом на базе этих асбтрагированных интерфейсов, проще написать несколько вариантов для разных ОС;
  • оба предыдущих пункта - как достаточно успешные попытки сделать абстрагированные интерфейсы, так и наоборот, написание платформозависимого кода для каждой нужной платформы - удорожают разработку. Везёт только в случаях, когда абстрагированные интерфейсы уже есть и достаточно хорошо выполняют свою задачу, как например Asio. Или хорошие кроссплатформенные стандартые API вроде OpenGL, что делает возможным писать кроссплафторменные игры.
  • разработчику ПО не нужно удорожание разработки там, где это не принесёт ощутимой выгоды.
Ответ написан
Комментировать
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Ну как бы на C++ пишут кроссплатформерные приложения, просто API разных платформ отличается и зачастую приходится юзать платформозависимый код или обёртки вроде Qt, где этот платформозависимый код скрыт. Другие технологии, как например Java делают тоже самое, только ещё больше это скрывают от программиста.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Си — язык очень близкий к железу. Когда мы пишем на Java, мы пишем код под Java-машину. На Си мы пишем код под процессор. Главная проблема, связанная с любыми подобными языками,— отсутствие понимания целевых ОС программистами и тестирования — тестерами. Это нужно, ибо абстрагирование от машины очень тонкое.

Поскольку перед нами очень тонкая прослойка, абстрагирующая от машины, приходится принимать меры, чтобы код переносился с машины на машину (даже с x86 на x64). Отлично это описано в блоге PVS-Studio.

В Windows и Linux машина-то одна и та же, но конкретно в Си++ к этому добавляется устаревшая по некоторым вещам стандартная библиотека. Примеры…
• Поддержка юникодных имён файлов пока не кроссплатформенная.
• Унаследоваться от std::ostream — ужос такой ещё.
• Как сконвертировать текст в UTF-8? Загугли и посмотри, какой там вавилон из шаблонов.
Отсюда огромное количество производителезависимых расширений, чужих библиотек, повторяющих стандартную, и прочее. Важный пункт тут: чужих библиотек, повторяющих стандартную. Если у тебя строки нестандартные и файлы нестандартные — какая тут кроссплатформенность?
Ответ написан
Комментировать
vesper-bot
@vesper-bot
Любитель файрволлов
Как минимум - разный порядок байт в 4-8-байтных словах, что мешает кроссплатформенно портировать битовые операции (&&,||,<<(<),>>(>) итд), так как порядок байт в константе внутри скомпилированного файла будет разным. Также - исполняемый код по-разному оформляется в файле, плюс API, которое по факту вызывается из исполняемого файла, в разных системах разное. Однако, кроссплатформенный код на С++ написать можно - но компилировать его надо в код некоей ВМ, а вот её уже компилировать под конкретную архитектуру. Как некоторые старые досовые игры делались - исполняемый модуль был разный для разных платформ, а код самой игры был общим.
Ответ написан
Тут уже много людей рассказало про техническую часть задачи, расскажи про продуктовую:

1) Работа с абстрактным слоем достаточно трудозатратна, а её перспективы весьма сомнительны, поэтому часто принимается волевое решение забить на часть юзеров и выбрать платформу, которая даст качественный, предсказуемый результат, для наиболее ценной части аудитории.

2) Если мы говорим не про внутренние решения, которые могут иметь любой вид и дистрибуцию, то часто кроссплатформенные фреймворки на C++ (и их порты на тот же Python) не могут дать продукт с наивысшим качеством использования пользователем, и усложняют дистрибуцию. (Либо приходится урезать функционал программы, что плохо с точки зрения продукта)

3) Рано или поздно компания приходит к выводу, что дешевле поддерживать основную платформу, а для других дать веб-морду, чем тратить время и ресурсы на кросс
Ответ написан
Комментировать
BacCM
@BacCM
C++ почти с рождения
Смотря на каком уровне нужна кросплатформенность. На уровне исходных кодов много пишут, для этого C кстати и разрабатывался изначально.
На уровне скомпилированных программ это только если Managed C++ и иже с ним
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Taraflex
@Taraflex
Ищу работу. Контакты в профиле.
Что не даёт

Есть лишь один правдивый ответ - бюджет.
Если же ПО бесплатное, то рассматриваем бюджет как отрицательную величину.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы