Почему невозможно создать декомпилятор C ++, который будет функционировать так же точно, как и для Java и C #?
Есть несколько причин:
Встраивание. Большая часть кода на C ++ встроена в оптимизированные сборки. Это разрушает любую форму декомпилятора. Чтобы выяснить, что функция была встроенной, декомпилятор должен будет проанализировать особенности встроенного кода и сопоставить их. И шаги оптимизации после встраивания могут сделать код очень различным, в зависимости от того, где он был встроен.
Шаблоны. Шаблоны используют исключительно # 1, но они создают дополнительные проблемы. По крайней мере теоретически возможно, что функция, которая встроена в двух местах, будет компилироваться в одну и ту же последовательность инструкций по сборке. Но для шаблона кода, который был создан с различными аргументами шаблона? Различные экземпляры обычно должны компилироваться в разные последовательности инструкций. И это становится еще сложнее, так как код шаблона может вызывать различные наборы функций на основе параметров шаблона. И сами эти функции могут быть встроены.
Выполнение во время компиляции. Шаблонное метапрограммирование позволяет компилятору фактически выполнять код. Но C ++ 11 constexpr
предоставляет более естественный способ сделать некоторые вычисления во время компиляции. Очевидно, что вызовы функций во время компиляции или реализации метафункций не могу быть частью скомпилированного исполняемого файла. Только результаты из них будут (так как в этом вся суть).
Отсутствие всестороннего отражения во время выполнения. В C # и Java оба байт-кода содержат много информации о природе исходного кода. Определения объектов легко обнаруживаются, как и имена объектов, типы и имена переменных-членов и т. Д. C ++ компилируется до машинного языка, который не обязан иметь такую информацию. И поскольку это не требуется, компиляторы не генерируют его. Даже группа по изучению рефлексии комитета ISO C ++ сосредоточена на время компиляции отражение, которое является информацией, которая не будет доступна во время выполнения.
Четное std::type_info
ничего не предлагает Причина в том, что, если компилятор не обнаружит, что определенный тип будет иметь typeid
вызывается, то компилятору не нужно генерировать std::type_info
объект для этого. И даже если это так, все, что вам дает, это имя объекта (и идентификатор). Ничего более.
Поскольку компиляторы C ++ обычно не помещают в исполняемый файл больше информации, чем им абсолютно необходимо (особенно если они компилируются не в отладочной сборке, а в режиме выпуска), поэтому информация, которая вам необходима для точной декомпиляции программы, просто не присутствует в исполняемом файле.
Конечно, может быть создан компилятор C ++, который включает в себя всю необходимую информацию в исполняемом файле (например, в наиболее наивной реализации, он может просто включать копию самого исходного кода в исполняемый файл), но это сделает исполняемые файлы значительно больше, и большинство разработчиков C ++ не с открытым исходным кодом предпочли бы, чтобы другие люди не быть в состоянии декомпилировать исполняемый файл, чтобы не было особого спроса на эту функциональность.