Почему многие виртуальные машины написаны на C, хотя выглядят так, будто у них есть функции C++?
-
13-09-2019 - |
Вопрос
Я заметил некоторые не очень старые языки виртуальных машин, такие как Lua, NekoVM и Potion, написанные на C.
Похоже, они переопределяли многие функции C++.
Есть ли смысл писать их на C, а не на C++?
Решение
Я кое-что знаю о Луа.
Lua написан на чистом стандарте ANSI C и компилируется на любой платформе ANSI без ошибок и предупреждений.Таким образом Lua работает практически на любой платформе мира., включая такие вещи, как Камеры Canon PowerShot.Гораздо сложнее заставить C++ работать на странных маленьких встроенных платформах.
Lua — это высокопроизводительная виртуальная машина, и поскольку C не может выражать вызовы методов (которые могут быть виртуальными, а могут и нет) и перегрузку операторов, это очень важно. легче предсказать производительность кода C просто взглянув на код.C++, особенно с библиотекой шаблонов, позволяет слишком легко сжигать ресурсы, даже не подозревая об этом.(Полная реализация Lua, включая не только виртуальную машину, но и библиотеки, умещается в 145 КБ объектного кода x86.Весь язык умещается даже в крошечном кэше емкостью 256 КБ, который находится на уровне L2 на Intel i7 и L1 на старых чипах.Если вы действительно не знаете, что делаете, гораздо сложнее написать C++, который компилируется во что-то настолько маленькое.)
Это две веские причины написать виртуальную машину на C.
Другие советы
Похоже, они переопределяли многие функции C++.
Вы предполагаете, что полиморфизм проще реализовать на C++, чем на C?Я думаю, что вы сильно ошибаетесь.
Если вы пишете виртуальную машину на C++, вы не будете реализовывать полиморфизм в терминах полиморфизма C++.Вы бы создали свою собственную виртуальную таблицу, которая сопоставляет имена функций с указателями или что-то в этом роде.
Люди привыкли к C.Должен признать, что для своих проектов я скорее буду писать на C, хотя пишу на C++ начиная с cfront 1.0.
Если вам нужен полный контроль над вещами, C немного проще.
Один очевидный ответ — совместимость.Каждый раз, когда язык X должен вызывать функции, определенные в языке Y, вы обычно проверяете, что либо X, либо Y — это C (то есть язык C)
C++ не определяет ABI, поэтому вызов кода C++ с другого языка немного сложнее сделать переносимым.Но вызов кода C почти тривиален.Это означает, что по крайней мере часть вашей виртуальной машины, вероятно, придется написать на C, и тогда почему бы не проявить последовательность и не написать все на C?
Еще одним преимуществом C является его простота.Его может прочитать каждый, и есть множество программистов, которые помогут вам его написать.C++, как хорошо, так и плохо, в большей степени является языком экспертов.На C++ можно сделать много впечатляющих вещей, и это может сэкономить вам много работы, но программистов, которые действительно хороши в этом, меньше.
Гораздо труднее быть «хорошим» в C++, и пока человек не станет хорош в этом, у него будет много ошибок и проблем.Теперь, особенно при работе над большими проектами с большим количеством людей, вероятность того, что один из них окажется недостаточно хорошим, намного выше, поэтому кодирование проекта на C часто менее рискованно.Существуют также проблемы с переносимостью: код C гораздо легче переносить между компиляторами, чем C++.
Lua также имеет множество функций, которые очень легко реализовать в Lisp, так почему бы не взять это за основу?Дело в том, что C — это не более чем прославленный ассемблерный код с тонким слоем абстракции.Это похоже на отполированный чистый лист, на котором вы можете строить абстракции более высокого уровня.C++ является таким зданием.Lua — это другая конструкция, и если бы ему пришлось использовать абстракции C++, ему пришлось бы ориентироваться на существующую структуру C++.Вместо этого, начав с чистого листа, вы сможете строить все так, как хотите.
Во многих случаях код на C может быть намного быстрее, чем на C++.Например, большинство функций в библиотеке stdio.c работают быстрее, чем iostream.scanf быстрее, чем cin, printf быстрее, чем cout и т. д.
а виртуальные машины требуют высокой производительности, поэтому код C имеет смысл, хотя разработка программ, скорее всего, потребует больше времени.
С++ реализован на языке C.Я подозреваю, что все следовали подходу C++.
Несмотря на то, что современные компиляторы C++ пропускают (или скрывают) явную трансляцию C++ в C как отдельный шаг, язык C++ имеет особенности, вытекающие из базовой реализации C.
Два примера.
Указатели в дополнение к ссылкам — это полностью заслуга C.Ссылок достаточно, и именно так работают Java, Python и Ruby.
Классы не являются объектами первого класса, существующими во время выполнения, поскольку класс — это всего лишь способ определить атрибуты и функции метода в базовом коде C.Объекты классов существуют во время выполнения в Java, Python и Ruby, и ими можно манипулировать.
Небольшое примечание: вам следует изучить источники CLR (воплощение Rotor) и Java, и вы заметите, что это гораздо больше C++-as-C, чем современный или хороший C++.Таким образом, здесь есть параллель, и это побочный эффект абстрагирования игрушек и обеспечения средней производительности для толпы на управляемых языках.
Это также помогает избежать ловушек наивного использования C++.Исключения и все прочее (кусочки, которые Дэвид начал в консалтинге по ускорению, и многое другое, пока мы создавали секвенсоры и семплирование звука еще до того, как он устроился на работу :) тоже являются проблемой..
Интеграция Python — это другой вопрос, и, например, у него неприятная история в Boost.Но для примитивных типов данных и интерфейсов/взаимодействия и машинной абстракции совершенно ясно, что ничто не сравнится с C.Никаких проблем с компилятором также нет, и он по-прежнему загружает многие вещи, прежде чем вы доберетесь до чего-то столь же влиятельного, каким оно есть/было/будет.
Степанов признал это достижение, когда прибил STL, а Бьярне прибил его с помощью шаблонов.Это три вещи, о которых всегда стоит думать, поскольку у вас нет достойного воплощения их в популярных управляемых языках, не говоря уже о такой выразительности и мощи.Все это более 20 лет спустя, что примечательно, и все еще загружается через C/C++.Наследие добра (но я не защищаю код C «темного века» c1982-2000, просто идея: вы можете использовать что угодно неправильно).