Как я могу получить размер функции C ++? - PullRequest
2 голосов
/ 02 января 2011

Как узнать размер функции в C ++?

Допустим, у меня есть функция:

void f()
{
/*do something*/
}

... Под "размером f" я подразумеваю размер кода /*do something*/, начиная с адреса, указанного указателем на f.

Ответы [ 7 ]

12 голосов
/ 02 января 2011

Вы не можете.Это может даже не быть четко определенной концепцией.Например, рассмотрим следующий код:

int f(int a) {
    return (3*a)+1;
}

int g(int a) {
    return (2*a)+1;
}

Я сомневаюсь, что это происходит на практике для этого конкретного примера, поскольку это не будет оптимизацией, но компилятору разрешено вводить блок кода, который вычисляетa+1 затем возвращается и переходит к этому блоку с каждой из точек входа f и g (после выполнения умножения в каждом случае).Какой тогда будет размер f?Должен ли он включать размер общего блока?Половина этого размера?С точки зрения C ++ не имеет смысла утверждать, что функция f имеет размер.

Кроме того, «указатель на f» может не просто быть адресом функции f.Это, безусловно, дает возможность добраться до точки входа f, но, например, на процессоре ARM в режиме межсетевого взаимодействия указатель на функцию, состоящую из кода Thumb, фактически является адресом первой инструкции плюс 1. В действительностиlsb указателя маскируется процессором при выполнении перехода к функции, но этот бит говорит процессору переключиться в режим большого пальца, а не в режим ARM.Таким образом, значение указателя не является адресом функции (хотя он близок).В любом случае, точка входа функции не обязательно должна быть в начале ее - если ваш компилятор создает постоянные пулы или аналогичные, они могут предшествовать исполняемому коду.

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

4 голосов
/ 02 января 2011

Ну, технически я не верю, что вы можете, не переносимо.

Но практически вы вполне можете сделать это:

void f() { ... }
void g() { ... }

char *fp = (char *)&f;
char *gp = (char *)&g;

int size = gp - fp;

Вы полагаетесь на то, что компилятор поставит 'g' после 'f' в объектном файле, и что компоновщик последует его примеру, поместив g после f.

Тогда вы просто вычитаете указатели, чтобы получить разницу.

Скорее всего, будут также возникать дополнения и другие возможные проблемы, поэтому размер функции может быть "не совсем".

3 голосов
/ 02 января 2011

Большинство компиляторов имеют возможность вывода сборки.Сделайте это, посмотрите инструкции в документации к вашему процессору и сделайте математику.

1 голос
/ 02 января 2011

Я предлагаю вам сделать что-то вроде strlen, за исключением того, что вы используете возвращаемый код операции вместо нуля в качестве терминатора.

1 голос
/ 02 января 2011

с текстовым редактором и wc?:) До сих пор неясно, что вы подразумеваете под размером функции, но я предполагаю, что вы имеете в виду размер машинного кода функции.Там нет никакого способа сделать это, особенно один переносимый через компиляторы.Многие компиляторы просто конвертируют программу в сборку, поэтому они не знают размер машинного кода.

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

0 голосов
/ 03 января 2011

Функции не имеют «размера».Что касается C ++, то они не являются объектами и не занимают места для хранения.На практике, конечно, они существуют в виде инструкций выполнения в результирующем исполняемом двоичном файле.

0 голосов
/ 02 января 2011

Я хочу получить размер сгенерированного кода в байтах, чтобы я мог скопировать код в новое местоположение и выполнить его оттуда.Я знаю, что это возможно, потому что я сделал это, используя 2 функции и метод вычитания.char * gp = (char *) & g;
int size = gp - fp;и это работало в visual studio в режиме релиза.Причина, по которой я задаю этот вопрос, заключается в том, что у меня все еще есть проблемы с оптимизацией компилятора, и мне нужен более безопасный метод.

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