Подтвердить что ты не робот

Как получить длину функции в байтах?

Я хочу знать длину функции C (написанную мной) во время выполнения. Любой способ получить его? Кажется, sizeof здесь не работает.

4b9b3361

Ответ 1

В стандарте C нет способа получить объем памяти, занимаемый функцией.

Ответ 2

Существует способ определить размер функции. Команда:

 nm -S <object_file_name>

Это вернет размеры каждой функции внутри объектного файла. Обратитесь к страницам руководства в GNU с помощью "man nm", чтобы получить дополнительную информацию об этом.

Ответ 3

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

mysec_start = .;
*(.mysection)
mysec_end = .;

Затем вы можете специально назначить функцию этому разделу. Разница между символами - это длина функции:

#include <stdio.h>

int i;

 __attribute__((noinline, section(".mysection"))) void test_func (void)
{
    i++;
}

int main (void)
{
    extern unsigned char mysec_start[];
    extern unsigned char mysec_end[];

    printf ("Func len: %lu\n", mysec_end - mysec_start);
    test_func ();

    return 0;
}

Этот пример предназначен для GCC, но любая инструментальная цепочка C должна иметь способ указать, в каком разделе назначить функцию. Я проверил бы результаты по списку сборки, чтобы убедиться, что он работает так, как вы хотите.

Ответ 4

Исполняемые файлы (по крайней мере, те, которые содержат информацию об отладке) не сохраняют функциональные длины. Таким образом, нет возможности анализировать эту информацию во время выполнения самостоятельно. Если вам нужно манипулировать функциями, вы должны что-то сделать с вашими объектами в фазе ссылок или путем доступа к ним в виде файлов из вашего исполняемого файла. Например, вы можете сообщить компоновщику, чтобы связать таблицы символов как раздел обычных данных с исполняемым файлом, назначить им какое-то имя и проанализировать, когда программа запускается. Но помните, что это было бы специфично для вашего компоновщика и формата объекта.

Также обратите внимание, что макет функции также специфичен для платформы, и есть некоторые вещи, которые делают термин "длина функции" неясным:

  • Функции могут иметь встроенные константы в разделах кода непосредственно после кода функции и обращаться к ним с использованием относительной адресации с помощью ПК (это делают компиляторы ARM).
  • Функции могут иметь "прологи" и "эпилоги", которые могут быть общими для нескольких функций и, таким образом, лежат вне основного тела.
  • Код функции может встроить другой код функции

Все они могут рассчитывать или не рассчитывать по длине функции.

Также функция может быть полностью встроена компилятором, поэтому она потеряет свое тело.

Ответ 5

В частности. Codewarrior, вы можете помещать метки вокруг функции, например.

label1:
void someFunc()
{
    /* code goes here. */
}
label2:

а затем вычислить размер как (int)(label2-label1), но это, очевидно, очень зависит от компилятора. В зависимости от вашей системы и компилятора вам может потребоваться взломать сценарии компоновщика и т.д.

Ответ 6

Начало функции - это указатель на функцию, вы уже знаете это.

Проблема заключается в том, чтобы найти конец, но это можно сделать следующим образом:

#include <time.h>

int foo(void)
{
   int i = 0;
   ++i + time(0); // time(0) is to prevent optimizer from just doing: return 1;
   return i;
}

int main(int argc, char *argv[])
{
   return (int)((long)main - (long)foo);
}

Он работает здесь, потому что у программы есть ТОЛЬКО ДВОЙНЫЕ функции, поэтому, если код переупорядочен (основной реализован до foo), тогда вы получите нерелевантный (отрицательный) расчет, чтобы вы знали, что он не работает таким образом, но это будет работать, если вы переместите код foo() в main() - просто вычтите основной() размер, полученный с первоначальным отрицательным ответом.

Если результат положительный, то он будет правильным - если не выполнено дополнение (да, некоторые компиляторы с радостью раздувают код, либо для выравнивания, либо для других, менее очевидных причин).

Окончание (int) (long) cast предназначено для переносимости между 32-битным и 64-битным кодом (указатели функций будут длиннее на 64-битной платформе).

Это неудобно переносимо и должно работать достаточно хорошо.

Ответ 7

В языке C не существует объекта, который возвращает длину функции; существует слишком много переменных (компилятор, целевой набор команд, файл объекта/исполняемый формат файла, параметры оптимизации, настройки отладки и т.д.). Тот же исходный код может привести к функциям разного размера для разных систем.

C просто не предоставляет каких-либо возможностей отражения для поддержки такого рода информации (хотя отдельные компиляторы могут предоставлять расширения, такие как пример Codewarrior, цитируемый sskuce). Если вам нужно знать, сколько байтов занимает ваша память в памяти, вам нужно будет напрямую изучить сгенерированный объект или исполняемый файл.

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

Ответ 8

Просто вычтите адрес своей функции из адреса следующей функции. Но обратите внимание, что это может не работать в вашей системе, поэтому используйте его, только если вы на 100% уверены:

#include <stdint.h>

int function() {
    return 0;
}

int function_end() {
    return 0;
}

int main(void) {
    intptr_t size = (intptr_t) function_end - (intptr_t) function;
}

Ответ 9

Нет стандартного способа сделать это либо на C, либо на С++. Естественно, существуют способы реализации/платформы для doiung it, но я не знаю ни о чем

Ответ 10

Я только что нашел решение для той же самой проблемы, но код, который я написал, зависит от платформы.

Идея заключается в том, чтобы поместить известные коды операций в конец функции и искать их с самого начала при подсчете пропущенных нами байтов. Вот средняя ссылка, которую я объяснил с помощью некоторого кода https://medium.com/@gurhanpolat/calculate-c-function-size-x64-x86-c1f49921aa1a

Ответ 11

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

int function1()
    {
    } 

int function2()
{
    int a,b;    //just defining some variable for increasing the memory size
    printf("This function would take more memory than earlier function i.e function01 ");
}

int main()
{
    printf("Printing the address of function01 %p\n",function01);
    printf("Printing the address of function02 %p\n",function02);
    printf("Printing the address of main %p\n",main);
    return 0;
}

Надеюсь, вы получите ответ после его компиляции. После компиляции вы сможете увидеть разница в размере функции01 и функции2.

Примечание. Обычно между одной функцией и другой существует 16 бит.