2013-02-03 7 views
2

Я знаю, что существуют различия в исходном коде между программами на C и C++ - это не, о чем я прошу.Разница между исполняемыми файлами C и C++?

Я также знаю, что это зависит от процессора и процессора и ОС от ОС, в зависимости от компилятора.

Я учу себя C++, и я видел многочисленные ссылки на библиотеки, которые могут использоваться обоими языками. Это заставило меня задуматься - существуют ли существенные различия между бинарными исполняемыми файлами двух языков?

Для того чтобы библиотеки были легко использованы обоими, я бы подумал, что они должны быть похожими на исполняемом уровне.

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

+3

Что вы действительно хотите задать, так это то, как функции (и в целом * символы *) экспортируются компиляторами любого языка ... –

+0

@Tango: нет никакой реальной разницы между двоичными файлами; они оба являются внутренним кодом, сохраненным в том же формате. – Mehrdad

+0

Исполняемый файл не имеет ничего общего с языком, который использовался для его создания. Если у вас было две программы, одна на C, а другая на C++, то и то и другое делалось точно так же, нет причин, по которым их исполняемые файлы не могли быть точно такими же. Однако компиляторы, как правило, оставляют все, что делает исполняемый файл идентифицируемым, поскольку он написан на определенном языке, но это совсем не обязательно. –

ответ

6

В большинстве случаев да, это довольно легко. Вот лишь несколько подсказок, которые я видел достаточно часто, чтобы запомнить их легко:

  1. Программа на C++, как правило, заканчивается хотя бы несколькими видимыми символами, которые были искалечены.
  2. программа
  3. C++ обычно будет иметь по крайней мере несколько вызовов на виртуальные функции, которые обычно весьма своеобразны от кода, который вы обычно будете видеть в С.
  4. Многих компиляторов C++ реализовать соглашение о вызовах для C++, который уделяет особое внимание для передачи указателя this в функции-члены C++. Опять же, поскольку указатель this просто не существует в C, вы редко увидите прямой аналог (хотя в некоторых случаях они будут использовать одно и то же соглашение для передачи некоторого другого указателя, поэтому вам нужно быть осторожным в этом) ,
1

На практике программа C (или программа на C++) редко является только чистым стандартным C (или C++) (например, стандарт C99 не имеет никакого значения для сканирования каталога). Поэтому программы используют дополнительные библиотеки.

В Linux большинство двоичных файлов динамически связаны. Используйте команду ldd, чтобы узнать.

Если бинарный файл связан с библиотекой stdc++, исходным кодом, скорее всего, является C++.

Если включена только библиотека libc.so, исходным кодом, вероятно, является только C (но вы можете связать статически библиотеку libstdc++.a).

Вы можете также использовать инструменты, работающие на бинарных файлов (например, objdump, readelf, strings, nm на Linux ....), чтобы узнать больше о них.

4

Исполняемый исполняемый файл является исполняемым, независимо от того, на каком языке он написан. Если он создан для целевой архитектуры, он будет работать на архитектуре.

The (возможно) наиболее важное различие между C и C++ - компилируемый код, а один отношение к библиотекам, которые могут быть связаны как с исполняемыми C и C++, является то, что name mangling. в принципе: когда библиотека компилируется, он экспортирует набор символов (имена функций, экспортируемые переменные и т. д.), которые могут использовать исполняемые файлы, связанные с библиотекой.Как эти символы являются с именем, является довольно специфичным для компилятора/компоновщика, и если последующий исполняемый файл связан с помощью компоновщика с использованием несовместимого соглашения, символы не будут корректно разрешаться. Кроме того, C и C++ имеют несколько разные соглашения. Статья в Википедии, приведенная выше, содержит больше деталей; достаточно сказать, что при объявлении экспортированных символов в файле заголовок, вы обычно видите конструкцию, как:

#ifdef __cplusplus 
extern "C" { 
#endif 

/* exported declarations here */ 

#ifdef __cplusplus 
} 
#endif 

__cplusplus препроцессора макрос определен только при компиляции C++ кода. Идея здесь заключается в том, что при использовании заголовка на C++ компилятору дается указание использовать способ именования экспортированных символов C (внутри блока extern "C" { /* foo */ }), поэтому библиотека может быть связана как на C, так и на C++ правильно.

+0

Кроме того, танго - это не бальный танец! :-П – sheu

1

код, сгенерированный компилятором C и C++, как правило, тот же код есть два важных отличия:.

  • Имя коверкание:. Каждая функция и глобальная переменная становится символ во время компиляции в C эти имена символа являются так же как и их имена в исходном коде. В C++ они немного искажены, чтобы разрешить полиморфный код
  • Соглашения о вызовах: если вы вызываете метод в C++, этот указатель передается как скрытый первый параметр. Другие конвенции также могут быть различными, например, как призыв ссылки, который не существует в C

Вы можете использовать блок, например, как это позволить C++ - компилятор генерирует код, совместимый с C:

extern "C" { 
    /* code */ 
} 
2

I думаю Я мог бы сказать, есть ли что-то C++ или C от чтения дизассемблированного двоичного кода [для архитектуры процессора, с которой я знаком, x86, x86_64 и ARM]. Но на самом деле нет большой разницы, вам нужно будет выглядеть довольно трудно, чтобы точно знать.

Знаки, которые необходимо искать, являются «косвенными вызовами» (function pointer calls via a table) и this. Хотя C может иметь аргументы pointer to struct и часто будет использовать указатели на функции, он обычно не устанавливается так, как это делает C++. Кроме того, иногда вы заметите, что компилятор берет указатель на структуру и добавляет небольшое смещение - это удаление внешнего слоя унаследованного класса. Это МОЖЕТ также произойти в C, но это не будет так же распространено/отличительно.

Глядя только на двоичную систему [если вы не можете «разборки в голове» было бы намного сложнее - особенно если ее лишили символов), это похоже на парня, который мог бы рассказать вам, какая классическая музыка была на старой Виниловая пластинка от просмотра дорожек [с ярлыком скрыта] - не то, что может сделать большинство людей, даже если они «хороши».

Смежные вопросы