StaticZ пишет:
На самом деле не совсем, можно спокойно посмотреть выдаваемый компилятором код MSIL и при желании даже вручную писать на нем и встраивать его в свой код. Конечно это не машинный код, однако по факту это некая абстракция ассемблера. И хоть по нему нельзя с уверенностью судить о машинном коде, тем не менее можно его оптимизировать.
Здесь вопрос соответствия архитектуры виртуальной машины и реального железа. Например в vmware, virtualbox, hyperv виртуальная машина является подмножеством реальной (по сути даже использует аппаратную виртуализацию процессора) и практически не уступает по скорости реальным вычислениям, код фактически как есть проецируется на реальное железо. Байт-код C#/Java работает на разных железах (например arm), видимо виртуальная машина их представляет некую абстракцию. В реальном асме указано за сколько тактов выполняется та или иная инструкция. В байт-коде можно написать более оптимизированный код для виртуальной машины, но может возникнуть проблема эмуляции специфических команд и реальное выполнение окажется медленнее, чем до оптимизации. Достаточно непредсказуемый процесс чтобы его контролировать. Нужно глубоко понимать работу виртуальных машин (а они ведь закрытые?) чтобы управлять этим процессом.
StaticZ пишет:
Ой ли? Вы правда можете ручаться что 1000 строк кода спустя компилятор не решит что данный код лучше скомпелить по другому?
С отключенной оптимизацией компиляторы действуют довольно прямолинейно и одинаково. К тому же всякие GCC обычно поясняют своё решение и даже комментируют выходные листинги ассемблера. Моё мнение что нужно писать без оптимизации пока есть такая возможность. Оптимизацию включить когда всё готово и все баги ручного кода отлажены. А если ручной код достаточно быстрый, то вообще оптимизацию не включать. Она реально может порождать баги и непредсказуемые действия. Я её рассматриваю как дополнительную плюшку: если прокатит -- здорово, если нет -- нужно рассчитывать на свои силы.
StaticZ пишет:
Я не говорю уже о том что смена компилятора или даже версии часто порождает кучу лулзов на эту тему
Здесь я так делаю: выбираю компилятор сразу на весь проект. Если проект -- движок, значит это на несколько лет вперёд. Некоторые люди даже версию компилятора не меняют, но я gcc-сборку время от времени обновляю, она достаточно консервативна, или по крайне мере указаны изменения. Если целевых платформ несколько, тогда действительно возникают трудности. Например msvs 2015 до сих пор не совместима с с++11/14 и там даже синтаксис немного отличается. Можно выйти из ситуации с помощью макросов, но это ухудшает читабельность кода. Поэтому я на windows использую mingw (сборка gcc для windows). Там тоже есть различия, но небольшие. Иногда проще написать два разных кода для своих целевых платформ на своих компиляторах. Или вот например скомпилировать движок и opengl рендер на gcc, а dll с directx рендером отдельно на msvs (потому что там есть интрументы для отладки dx11 хорошие), а затем слинковать вместе.
StaticZ пишет:
вроде различных правил при инициализации переменных (одни к примеру обнуляют значения другие нет)
В первую очередь надо полагаться на стандарт языка. с++ не предполагает зануление без явной инициализации, так что и рассчитывать на зануление компилятором не стоит. А чтобы это не приводило к скрытым багам, компилятор должен выдавать ворнинги. Если он зануляет скрытно, лучше не пользоваться таким компилятором.
StaticZ пишет:
В теории да, но на практике самое смешное, что все поклонники С++ не могут жить без всяких STD, BUST, автосборщиков мусора и новомодных наворотов, вплоть до тех же лямбда выражений. А ведь весь этот тяжелый мусор ничем не лучше аналогичных высокоуровневых конструкций в том же C#, как с точки зрения скорости так и сточки зрения возможности низкоуровневой оптимизации.
Быть поклонником языка это плохо, нужно мыслить вне рамок языка =). Ну вообще то непосредственно в геймдеве осуждается использовать "новомодные навороты". boost однозначно критикуется в геймдеве и про него нужно забыть. Под автосборщиком мусора понимается управление памятью: обычно используют стандартное ручное, или же пишут специально для движка своё. std начиная с с++11 стал лучше, его можно использовать чтобы быстро наклепать прототип или пробную версию, но в процессе оптимизации std потихоньку заменяют на свой код в критических по скорости местах. Но в целом std это уже часть языка. А вот лямбда это конструкция ядра языка, так что это никак не наворот, это такая же базовая вещь как вызов функций, просто относительно новая и не все привыкли. Скорость она никак не портит, просто форма записи такая для удобства, она как inline функция в место вызова подставляет свой код.
Вот у вас тут все проекты в целом одинаковые с технической точки зрения. Можно написать под них сразу один движок. Он не универсальный, а под конкретный набор игр будет. И сразу на несколько лет вперёд перспектива.